home *** CD-ROM | disk | FTP | other *** search
/ One Click 11 / OneClick11.iso / Manuntencao / Reparo / SQL Server 2000 Security Tools 8 / SQLCritUpdPkg_ENU.exe / SQLCritUpd / SQLHotfix_ENU.exe / Hotfix3 / Files / replsys.sql < prev    next >
Encoding:
Text File  |  2001-10-03  |  963.8 KB  |  30,675 lines

  1.  
  2. /*
  3. ** replsys.sql            1997/02/12 22:03
  4. **
  5. **
  6. ** Copyright Microsoft, Inc. 1998-2000
  7. ** All Rights Reserved.
  8. */
  9.  
  10.  
  11. dump tran master with no_log
  12. go
  13.  
  14. exec dbo.sp_configure 'update',1
  15. go
  16. reconfigure with override
  17. go
  18.  
  19. set ANSI_NULLS off
  20. go
  21.  
  22. use master
  23. go
  24.  
  25. exec dbo.sp_MS_upd_sysobj_category 1 --Capture time for use at the end
  26. go
  27.  
  28. if exists( select * from sysobjects 
  29.     where type = 'P ' and name = N'sp_getarticlepkcolbitmap')
  30. begin
  31.     drop procedure sp_getarticlepkcolbitmap
  32. end
  33. go
  34.  
  35. if exists( select * from sysobjects 
  36.     where type = 'P ' and name = N'sp_isarticlecolbitset' )
  37. begin
  38.     drop procedure sp_isarticlecolbitset
  39. end
  40. go
  41.  
  42. if exists (select * from sysobjects
  43.     where type = 'P '
  44.             and name = 'sp_MSsubst_filter_name')
  45.     drop procedure sp_MSsubst_filter_name
  46. go
  47.  
  48. if exists (select * from sysobjects
  49.     where type = 'P '
  50.             and name = 'sp_MSretrieve_publication_attributes')
  51.     drop procedure sp_MSretrieve_publication_attributes
  52. go
  53.  
  54. if exists (select * from sysobjects
  55.     where type = 'P '
  56.             and name = 'sp_MScleanup_publication_ADinfo')
  57.     drop procedure sp_MScleanup_publication_ADinfo
  58. go
  59.  
  60. if exists (select * from sysobjects
  61.     where type = 'P '
  62.             and name = 'sp_MSCleanupForPullReinit')
  63.     drop procedure sp_MSCleanupForPullReinit
  64.  
  65. if exists (select * from sysobjects
  66.     where type = 'P '
  67.             and name = 'sp_MSsubst_filter_names')
  68.     drop procedure sp_MSsubst_filter_names
  69. go
  70.  
  71. if exists (select * from sysobjects
  72.     where type = 'P '
  73.             and name = 'sp_MSreplcheck_name')
  74.     drop procedure sp_MSreplcheck_name
  75. go
  76.  
  77. if exists (select * from sysobjects
  78.     where type = 'P '
  79.             and name = 'sp_MSreplcheck_publish')
  80.     drop procedure sp_MSreplcheck_publish
  81. go
  82.  
  83. if exists (select * from sysobjects
  84.     where type = 'P '
  85.             and name = 'sp_MSsetaccesslist')
  86.     drop procedure sp_MSsetaccesslist
  87. go
  88.  
  89. if exists (select * from sysobjects
  90.     where type = 'P '
  91.             and name = 'sp_MScheck_subscription')
  92.     drop procedure sp_MScheck_subscription
  93. go
  94.  
  95. if exists (select * from sysobjects
  96.     where type = 'P '
  97.             and name = 'sp_MSenumcolumns')
  98.     drop procedure sp_MSenumcolumns
  99. go
  100.  
  101. if exists (select * from sysobjects
  102.     where type = 'P '
  103.             and name = 'sp_MSlocktable')
  104.     drop procedure sp_MSlocktable
  105. go
  106.  
  107. if exists (select * from sysobjects
  108.     where type = 'P '
  109.             and name = 'sp_MSreplcheck_connection')
  110.     drop procedure sp_MSreplcheck_connection
  111. go
  112.  
  113. if exists (select * from sysobjects
  114.     where type = 'P '
  115.             and name = 'sp_MSreplcheck_pull')
  116.     drop procedure sp_MSreplcheck_pull
  117. go
  118.  
  119. if exists (select * from sysobjects
  120.     where type = 'P '
  121.             and name = 'sp_MSchange_retention')
  122.     drop procedure sp_MSchange_retention
  123.  
  124. if exists (select * from sysobjects
  125.     where type = 'P '
  126.             and name = 'sp_MShelp_identity_property')
  127.     drop procedure sp_MShelp_identity_property
  128. go
  129.  
  130. if exists (select * from sysobjects
  131.     where type = 'P '
  132.             and name = 'sp_MSreplcheck_qv')
  133.     drop procedure sp_MSreplcheck_qv
  134. go
  135.  
  136. if exists (select * from sysobjects
  137.     where type = 'P' and
  138.             name = 'sp_MSreleaseSlotLock')
  139.     drop procedure sp_MSreleaseSlotLock
  140.  
  141. if exists (select * from sysobjects
  142.     where type = 'P' and
  143.             name = 'sp_MSacquireSlotLock')
  144.     drop procedure sp_MSacquireSlotLock
  145. go
  146.  
  147. if exists (select * from sysobjects
  148.     where type = 'P' and
  149.             name = 'sp_MSacquireHeadofQueueLock')
  150.     drop procedure sp_MSacquireHeadofQueueLock
  151. go
  152.  
  153. if exists (select * from sysobjects
  154.     where type = 'P '
  155.             and name = 'sp_MSpublicationcleanup')
  156.     drop procedure sp_MSpublicationcleanup
  157.  
  158. if exists (select * from sysobjects
  159.     where type = 'P '
  160.             and name = 'sp_MSUpgradeConflictTable')
  161.     drop procedure sp_MSUpgradeConflictTable
  162.  
  163. if exists (select * from sysobjects
  164.     where type = 'P '
  165.             and name = 'sp_MSaddanonymousreplica')
  166.     drop procedure sp_MSaddanonymousreplica
  167.         
  168. if exists (select * from sysobjects
  169.                 where type = 'P' and
  170.                 name = 'sp_reinitmergepullsubscription')
  171.         drop procedure sp_reinitmergepullsubscription
  172.  
  173. if exists (select * from sysobjects
  174.     where type = 'P '
  175.             and name = 'sp_expired_subscription_cleanup')
  176.     drop procedure sp_expired_subscription_cleanup
  177.     
  178.     if exists (select * from sysobjects
  179.     where type = 'P '
  180.             and name = 'sp_MSarticlecleanup')
  181.     drop procedure sp_MSarticlecleanup
  182.  
  183.  
  184.     if exists (select * from sysobjects
  185.     where type = 'P '
  186.             and name = 'sp_MSdroparticleprocs')
  187.     drop procedure sp_MSdroparticleprocs
  188.  
  189.     if exists (select * from sysobjects
  190.     where type = 'P '
  191.             and name = 'sp_MSdroparticletriggers')
  192.     drop procedure sp_MSdroparticletriggers
  193.  
  194.     if exists (select * from sysobjects
  195.     where type = 'P '
  196.             and name = 'sp_MScheckvalidsystables')
  197.     drop procedure sp_MScheckvalidsystables
  198.  
  199. if exists (select * from sysobjects
  200.     where type = 'P '
  201.             and name = 'sp_MSreplcheck_subscribe')
  202.     drop procedure sp_MSreplcheck_subscribe
  203. go
  204.  
  205. if exists (select * from sysobjects
  206.     where type = 'P '
  207.             and name = 'sp_replicationoption')
  208.     drop procedure sp_replicationoption
  209. go
  210.  
  211. if exists (select * from sysobjects
  212.     where type = 'P '
  213.             and name = 'sp_helpreplicationoption')
  214.     drop procedure sp_helpreplicationoption
  215. go
  216.  
  217. if exists (select * from sysobjects
  218.         where type in ('P ') 
  219.             and name = 'sp_MSmergesubscribedb')
  220.     drop procedure sp_MSmergesubscribedb
  221.  
  222. if exists (select * from sysobjects
  223.         where type in ('P ') 
  224.             and name = 'sp_MSremovedbreplication')
  225.     drop procedure sp_MSremovedbreplication
  226.  
  227. if exists (select * from sysobjects
  228.     where type = 'P '
  229.             and name = 'sp_addpullsubscription')
  230.     drop procedure sp_addpullsubscription
  231.  
  232. if exists (select * from sysobjects
  233.     where type = 'P '
  234.             and name = 'sp_reinitpullsubscription')
  235.     drop procedure sp_reinitpullsubscription
  236.     
  237. if exists (select * from sysobjects
  238.     where type = 'P '
  239.             and name = 'sp_addmergepullsubscription')
  240.     drop procedure sp_addmergepullsubscription
  241.  
  242. if exists (select * from sysobjects
  243.     where type = 'P '
  244.             and name = 'sp_dropmergepullsubscription')
  245.     drop procedure sp_dropmergepullsubscription
  246.  
  247. if exists (select * from sysobjects
  248.     where type = 'P '
  249.             and name = 'sp_adjustpublisheridentityrange')
  250.     drop procedure sp_adjustpublisheridentityrange
  251.  
  252. if exists (select * from sysobjects
  253.     where type = 'P '
  254.             and name = 'sp_changemergepullsubscription')
  255.     drop procedure sp_changemergepullsubscription
  256.  
  257. if exists (select * from sysobjects
  258.     where type = 'P '
  259.             and name = 'sp_helpmergepullsubscription')
  260.     drop procedure sp_helpmergepullsubscription
  261.  
  262. if exists (select * from sysobjects
  263.     where type = 'P '
  264.             and name = 'sp_MSchange_priority')
  265.     drop procedure sp_MSchange_priority
  266.  
  267. if exists (select * from sysobjects
  268.         where type = 'P '
  269.                 and name = 'sp_MSdrop_mergesystables')
  270.         drop procedure sp_MSdrop_mergesystables
  271.  
  272. if exists (select * from sysobjects
  273.         where type = 'P '
  274.                 and name = 'sp_MScreate_mergesystables')
  275.         drop procedure sp_MScreate_mergesystables
  276. go
  277.     
  278. if exists (select * from sysobjects
  279.     where type = 'P '
  280.             and name = 'sp_MSupdatesharedagentproperties')
  281.     drop procedure sp_MSupdatesharedagentproperties
  282.  
  283. if exists (select * from sysobjects
  284.     where type = 'P '
  285.             and name = 'sp_MSfixupsharedagentproperties')
  286.     drop procedure sp_MSfixupsharedagentproperties
  287.  
  288. if exists (select * from sysobjects
  289.     where type = 'P '
  290.             and name = 'sp_MSfixupdistributorinfo')
  291.     drop procedure sp_MSfixupdistributorinfo
  292.  
  293. if exists (select * from sysobjects
  294.     where type = 'P '
  295.             and name = 'sp_MSfixupdistributorsecurity')
  296.     drop procedure sp_MSfixupdistributorsecurity
  297.  
  298. if exists (select * from sysobjects
  299.     where type = 'P '
  300.             and name = 'sp_MSfixupftpinfo')
  301.     drop procedure sp_MSfixupftpinfo
  302.  
  303. if exists (select * from sysobjects
  304.     where type = 'P '
  305.             and name = 'sp_MSfixupaltsnapshotfolder')
  306.     drop procedure sp_MSfixupaltsnapshotfolder
  307.  
  308. if exists (select * from sysobjects
  309.     where type = 'P '
  310.             and name = 'sp_MSfixupworkingdirectory')
  311.     drop procedure sp_MSfixupworkingdirectory
  312.  
  313. if exists (select * from sysobjects
  314.     where type = 'P '
  315.             and name = 'sp_MSfixupuseftp')
  316.     drop procedure sp_MSfixupuseftp
  317.  
  318. if exists (select * from sysobjects
  319.     where type = 'P '
  320.             and name = 'sp_MSfixupagentoffloadinfo')
  321.     drop procedure sp_MSfixupagentoffloadinfo
  322.  
  323. go
  324.  
  325. if exists (select * from sysobjects
  326.     where type = 'P '
  327.             and name = 'sp_addpullsubscription_agent')
  328.     drop procedure sp_addpullsubscription_agent
  329.  
  330. if exists (select * from sysobjects
  331.     where type = 'P '
  332.             and name = 'sp_helpsubscription_properties')
  333.     drop procedure sp_helpsubscription_properties
  334.  
  335. if exists (select * from sysobjects
  336.     where type = 'P '
  337.             and name = 'sp_change_subscription_properties')
  338.     drop procedure sp_change_subscription_properties
  339.  
  340. if exists (select * from sysobjects
  341.     where type = 'P'
  342.             and name = 'sp_MSget_pullsubsagent_owner')
  343.     drop procedure sp_MSget_pullsubsagent_owner
  344.  
  345. if exists (select * from sysobjects
  346.     where type = 'P'
  347.             and name = 'sp_MSget_mergepullsubsagent_owner')
  348.     drop procedure sp_MSget_mergepullsubsagent_owner
  349.     
  350. if exists (select * from sysobjects
  351.     where type = 'P '
  352.             and name = 'sp_addmergepullsubscription_agent')
  353.     drop procedure sp_addmergepullsubscription_agent
  354.  
  355. if exists (select * from sysobjects
  356.     where type = 'P '
  357.             and name = 'sp_droppullsubscription')
  358.     drop procedure sp_droppullsubscription
  359.  
  360. if exists (select * from sysobjects
  361.     where type = 'P '
  362.             and name = 'sp_vupgrade_publisherdb')
  363.     drop procedure sp_vupgrade_publisherdb
  364.  
  365. if exists (select * from sysobjects
  366.     where type = 'P '
  367.             and name = 'sp_vupgrade_publisher')
  368.     drop procedure sp_vupgrade_publisher
  369.  
  370. if exists (select * from sysobjects
  371.     where type = 'P '
  372.             and name = 'sp_MScopyregvalue')
  373.     drop procedure sp_MScopyregvalue
  374.  
  375. if exists (select * from sysobjects
  376.     where type = 'P '
  377.             and name = 'sp_vupgrade_registry')
  378.     drop procedure sp_vupgrade_registry
  379.  
  380. -- this proc renamed
  381. if exists (select * from sysobjects
  382.     where type = 'P '
  383.             and name = 'sp_vupdate_syscol_status')
  384.     drop procedure sp_vupdate_syscol_status
  385.  
  386. if exists (select * from sysobjects
  387.     where type = 'P '
  388.             and name = 'sp_vupgrade_syscol_status')
  389.     drop procedure sp_vupgrade_syscol_status
  390.  
  391. if exists (select * from sysobjects
  392.     where type = 'P '
  393.             and name = 'sp_helppullsubscription')
  394.     drop procedure sp_helppullsubscription
  395.  
  396. if exists (select * from sysobjects
  397.     where type = 'P '
  398.             and name = 'sp_MSunmarkreplinfo')
  399.     drop procedure sp_MSunmarkreplinfo
  400.  
  401. if exists (select * from sysobjects
  402.     where type = 'P '
  403.             and name = 'sp_MSmarkreplinfo')
  404.     drop procedure sp_MSmarkreplinfo
  405.  
  406. if exists (select * from sysobjects
  407.     where type = 'P '
  408.             and name = 'sp_MSunmarkschemaobject')
  409.     drop procedure sp_MSunmarkschemaobject
  410.  
  411. if exists (select * from sysobjects
  412.     where type = 'P '
  413.             and name = 'sp_MSmarkschemaobject')
  414.     drop procedure sp_MSmarkschemaobject
  415.  
  416. if exists (select * from sysobjects
  417.     where type = 'P '
  418.             and name = 'sp_MSunmarkifneeded')
  419.     drop procedure sp_MSunmarkifneeded
  420.  
  421. if exists (select * from sysobjects
  422.         where type = 'P '
  423.                 and name = 'sp_MStable_has_unique_index')
  424.         drop procedure sp_MStable_has_unique_index
  425.  
  426. if exists (select * from sysobjects
  427.         where type = 'P '
  428.                 and name = 'sp_MSreplraiserror')
  429.         drop procedure sp_MSreplraiserror
  430.  
  431. if exists (select * from sysobjects
  432.         where type = 'P '
  433.                 and name = 'sp_check_sync_trigger')
  434.         drop procedure sp_check_sync_trigger
  435.  
  436. if exists (select * from sysobjects
  437.         where type = 'P '
  438.                 and name = 'sp_MSreplicationcompatlevel')
  439.     drop proc sp_MSreplicationcompatlevel    
  440.  
  441. if exists (select * from sysobjects
  442.         where type = 'P '
  443.                 and name = 'sp_MSgenreplnickname')
  444.     drop proc sp_MSgenreplnickname
  445.  
  446. if exists (select * from sysobjects
  447.         where type = 'P '
  448.                 and name = 'sp_MSenumallpublications')
  449.     drop proc sp_MSenumallpublications
  450.  
  451. if exists (select * from sysobjects
  452.         where type = 'P '
  453.                 and name = 'sp_MSenumallsubscriptions')
  454.     drop proc sp_MSenumallsubscriptions
  455.  
  456. if exists (select * from sysobjects
  457.         where type = 'P '
  458.                 and name = 'sp_MSenumsubscriptions')
  459.     drop proc sp_MSenumsubscriptions
  460.  
  461. if exists (select * from sysobjects
  462.         where type = 'P '
  463.                 and name = 'sp_MSenumtranpublications')
  464.     drop proc sp_MSenumtranpublications
  465.  
  466. if exists (select * from sysobjects
  467.         where type = 'P '
  468.                 and name = 'sp_MSenummergepublications')
  469.     drop proc sp_MSenummergepublications
  470.  
  471. if exists (select * from sysobjects
  472.         where type = 'P '
  473.                 and name = 'sp_MSenum3rdpartypublications')
  474.     drop proc sp_MSenum3rdpartypublications
  475.  
  476. if exists (select * from sysobjects
  477.         where type = 'P '
  478.                 and name = 'sp_MSenumthirdpartypublicationvendornames')
  479.     drop proc sp_MSenumthirdpartypublicationvendornames
  480.  
  481. if exists (select * from sysobjects
  482.                 where type = 'P' and
  483.                 name = 'sp_MSgetreplicainfo')
  484.         drop procedure sp_MSgetreplicainfo
  485.  
  486. if exists (select * from sysobjects
  487.     where type = 'P '
  488.            and name = 'sp_subscription_cleanup')
  489.      drop procedure sp_subscription_cleanup  
  490.  
  491. if exists (select * from sysobjects
  492.     where type = 'P '
  493.            and name = 'sp_mergesubscription_cleanup')
  494.      drop procedure sp_mergesubscription_cleanup  
  495.  
  496. if exists (select * from sysobjects
  497.     where type = 'P '
  498.             and name = 'sp_MSpad_command')
  499.     drop procedure sp_MSpad_command
  500.  
  501. if exists (select * from sysobjects
  502.     where type = 'P '
  503.             and name = 'sp_MSflush_command')
  504.     drop procedure sp_MSflush_command
  505.  
  506. if exists (select * from sysobjects
  507.     where type = 'P '
  508.             and name = 'sp_MSget_colinfo')
  509.     drop procedure sp_MSget_colinfo
  510.  
  511. if exists (select * from sysobjects
  512.     where type = 'P '
  513.             and name = 'sp_MSget_type')
  514.     drop procedure sp_MSget_type
  515.  
  516. if exists (select * from sysobjects
  517.     where type = 'P '
  518.             and name = 'sp_MSget_col_position')
  519.     drop procedure sp_MSget_col_position
  520.  
  521. if exists (select * from sysobjects
  522.     where type = 'P '
  523.             and name = 'sp_MSget_map_position')
  524.     drop procedure sp_MSget_map_position
  525.  
  526. if exists (select * from sysobjects
  527.     where type = 'P '
  528.             and name = 'sp_MSscript_where_clause')
  529.     drop procedure sp_MSscript_where_clause
  530.  
  531. if exists (select * from sysobjects
  532.     where type = 'P '
  533.             and name = 'sp_MSscript_params')
  534.     drop procedure sp_MSscript_params
  535.  
  536. if exists (select * from sysobjects
  537.     where type = 'P '
  538.             and name = 'sp_MSscript_procbodystart')
  539.     drop procedure sp_MSscript_procbodystart
  540.  
  541. if exists (select * from sysobjects
  542.     where type = 'P '
  543.             and name = 'sp_MSscript_begintrig1')
  544.     drop procedure sp_MSscript_begintrig1
  545.  
  546. if exists (select * from sysobjects
  547.     where type = 'P '
  548.             and name = 'sp_MSscript_begintrig2')
  549.     drop procedure sp_MSscript_begintrig2
  550.  
  551. if exists (select * from sysobjects
  552.     where type = 'P '
  553.             and name = 'sp_MSscript_endtrig')
  554.     drop procedure sp_MSscript_endtrig
  555.  
  556. if exists (select * from sysobjects
  557.     where type = 'P '
  558.             and name = 'sp_MSscript_trigger_variables')
  559.     drop procedure sp_MSscript_trigger_variables
  560.  
  561. if exists (select * from sysobjects
  562.     where type = 'P '
  563.             and name = 'sp_MSscript_trigger_assignment')
  564.     drop procedure sp_MSscript_trigger_assignment
  565.  
  566. if exists (select * from sysobjects
  567.     where type = 'P '
  568.             and name = 'sp_validatemergepullsubscription')
  569.     drop procedure sp_validatemergepullsubscription
  570.  
  571. if exists (select * from sysobjects
  572.     where type = 'P '
  573.             and name = 'sp_MSscript_trigger_fetch_statement')
  574.     drop procedure sp_MSscript_trigger_fetch_statement
  575.  
  576. if exists (select * from sysobjects
  577.     where type = 'P '
  578.             and name = 'sp_MSscript_trigger_exec_rpc')
  579.     drop procedure sp_MSscript_trigger_exec_rpc
  580.  
  581. if exists (select * from sysobjects
  582.     where type = 'P '
  583.             and name = 'sp_MSscript_trigger_update_checks')
  584.     drop procedure sp_MSscript_trigger_update_checks
  585.  
  586. if exists (select * from sysobjects
  587.     where type = 'P '
  588.             and name = 'sp_MSscript_trigger_updates')
  589.     drop procedure sp_MSscript_trigger_updates
  590.  
  591. if exists (select * from sysobjects
  592.     where type = 'P '
  593.             and name = 'sp_MSscript_singlerow_trigger')
  594.     drop procedure sp_MSscript_singlerow_trigger
  595.  
  596. if exists (select * from sysobjects
  597.     where type = 'P '
  598.             and name = 'sp_MSscript_multirow_trigger')
  599.     drop procedure sp_MSscript_multirow_trigger
  600.  
  601. if exists (select * from sysobjects
  602.     where type = 'P '
  603.             and name = 'sp_MSscript_sync_ins_trig')
  604.     drop procedure sp_MSscript_sync_ins_trig
  605.  
  606. if exists (select * from sysobjects
  607.     where type = 'P '
  608.             and name = 'sp_MSscript_sync_upd_trig')
  609.     drop procedure sp_MSscript_sync_upd_trig
  610.  
  611. if exists (select * from sysobjects
  612.     where type = 'P '
  613.             and name = 'sp_MSscript_sync_del_trig')
  614.     drop procedure sp_MSscript_sync_del_trig
  615.  
  616. if exists (select * from sysobjects
  617.     where type = 'P '
  618.             and name = 'sp_MSget_synctran_column')
  619.     drop procedure sp_MSget_synctran_column
  620.  
  621. if exists (select * from sysobjects
  622.     where type = 'P '
  623.             and name = 'sp_check_for_sync_trigger')
  624.     drop procedure sp_check_for_sync_trigger
  625.  
  626. if exists (select * from sysobjects
  627.     where type = 'P '
  628.             and name = 'sp_addqueued_artinfo')
  629.     drop procedure sp_addqueued_artinfo    
  630.  
  631. if exists (select * from sysobjects
  632.     where type = 'P '
  633.             and name = 'sp_addsynctriggers')
  634.     drop procedure sp_addsynctriggers
  635.  
  636. if exists (select * from sysobjects
  637.     where type = 'P '
  638.             and name = 'sp_setreplfailovermode')
  639.     drop procedure sp_setreplfailovermode
  640.  
  641. if exists (select * from sysobjects
  642.     where type = 'P '
  643.             and name = 'sp_helpreplfailovermode')
  644.     drop procedure sp_helpreplfailovermode
  645.  
  646. if exists (select * from sysobjects
  647.         where type = 'P '
  648.             and name = 'sp_helpreplicationdboption')
  649.     drop procedure sp_helpreplicationdboption
  650.  
  651. if exists (select * from sysobjects
  652.         where type = 'P' and name = 'sp_MSgetreplnick')
  653.     drop procedure sp_MSgetreplnick
  654.         
  655. if exists (select * from sysobjects
  656.         where type = 'P' and name = 'sp_MStestbit')        
  657.     drop procedure sp_MStestbit
  658.         
  659. if exists (select * from sysobjects
  660.         where type = 'P' and name = 'sp_MSsetbit')
  661.     drop procedure sp_MSsetbit
  662.         
  663.         
  664. if exists (select * from sysobjects
  665.         where type = 'P' and name = 'sp_MSinsertcontents')
  666.     drop procedure sp_MSinsertcontents
  667.         
  668. if exists (select * from sysobjects
  669.         where type = 'P' and name = 'sp_MSupdatecontents')
  670.     drop procedure sp_MSupdatecontents
  671.             
  672. if exists (select * from sysobjects
  673.         where type = 'P' and name = 'sp_MSdeletecontents')
  674.     drop procedure sp_MSdeletecontents
  675.  
  676. if exists (select * from sysobjects
  677.         where type = 'P '
  678.             and name = 'sp_MSadd_repl_job')
  679.     drop procedure sp_MSadd_repl_job
  680.  
  681. IF EXISTS (select * from sysobjects where
  682.    name = 'sp_MScheck_agent_instance' and type = 'P')
  683.       DROP PROCEDURE sp_MScheck_agent_instance
  684.  
  685. IF EXISTS (select * from sysobjects where
  686.    name = 'sp_MSenum_replsqlqueues' and type = 'P')
  687.       DROP PROCEDURE sp_MSenum_replsqlqueues
  688.  
  689. IF EXISTS (select * from sysobjects where
  690.    name = 'sp_MSenum_replqueues' and type = 'P')
  691.       DROP PROCEDURE sp_MSenum_replqueues
  692.  
  693. if exists (select * from sysobjects
  694.         where name = 'xp_mergexpusage')
  695.     execute dbo.sp_dropextendedproc 'xp_mergexpusage'
  696.  
  697. if exists (select * from sysobjects 
  698.         where name = 'sp_get_distributor' 
  699.                 and type = 'P')
  700.       drop procedure sp_get_distributor
  701.  
  702. if exists (select * from sysobjects 
  703.         where name = 'sp_MSrepl_addrolemember' 
  704.                 and type = 'P')
  705.       drop procedure sp_MSrepl_addrolemember
  706.  
  707. if exists (select * from sysobjects 
  708.         where name = 'sp_MSrepl_droprolemember' 
  709.                 and type = 'P')
  710.       drop procedure sp_MSrepl_droprolemember
  711.  
  712. if exists (select * from sysobjects 
  713.         where name = 'sp_table_validation' 
  714.                 and type = 'P')
  715.       drop procedure sp_table_validation
  716.  
  717. if exists (select * from sysobjects 
  718.         where name = 'sp_MScreate_sub_tables' 
  719.                 and type = 'P')
  720.       drop procedure sp_MScreate_sub_tables
  721. go
  722.  
  723. if exists (select * from sysobjects 
  724.         where name = 'sp_MSupdate_mqserver_subdb' 
  725.                 and type = 'P')
  726.       drop procedure sp_MSupdate_mqserver_subdb
  727.  
  728. if exists (select * from sysobjects 
  729.         where name = 'sp_removedbreplication' 
  730.                 and type = 'P')
  731.       drop procedure sp_removedbreplication
  732.  
  733. if exists (select * from sysobjects 
  734.         where name = 'sp_MSBumpupCompLevel' 
  735.                 and type = 'P')
  736.       drop procedure sp_MSBumpupCompLevel
  737.  
  738. if exists (select * from sysobjects 
  739.         where name = 'sp_cleanupdbreplication' 
  740.                 and type = 'P')
  741.       drop procedure sp_cleanupdbreplication
  742.  
  743. if exists (select * from sysobjects 
  744.         where name = 'sp_removesrvreplication' 
  745.                 and type = 'P')
  746.       drop procedure sp_removesrvreplication
  747.  
  748. if exists (select * from sysobjects 
  749.         where name = 'sp_vupgrade_subscription_databases' 
  750.                 and type = 'P')
  751.       drop procedure sp_vupgrade_subscription_databases
  752.  
  753. if exists (select * from sysobjects 
  754.         where name = 'sp_vupgrade_MSsubscription_properties' 
  755.                 and type = 'P')
  756.       drop procedure sp_vupgrade_MSsubscription_properties
  757.  
  758. if exists (select * from sysobjects 
  759.         where name = 'sp_vupgrade_mergetables' 
  760.                 and type = 'P')
  761.       drop procedure sp_vupgrade_mergetables
  762.  
  763. if exists (select * from sysobjects 
  764.         where name = 'sp_vupgrade_subpass' 
  765.                 and type = 'P')
  766.       drop procedure sp_vupgrade_subpass
  767.  
  768. if exists (select * from sysobjects 
  769.         where name = 'sp_vupgrade_subscription_tables' 
  770.                 and type = 'P')
  771.       drop procedure sp_vupgrade_subscription_tables
  772.  
  773. if exists (select * from sysobjects 
  774.         where name = 'sp_vupgrade_replication' 
  775.                 and type = 'P')
  776.       drop procedure sp_vupgrade_replication
  777.  
  778. if exists (select * from sysobjects 
  779.         where name = 'sp_vupgrade_distdb' 
  780.                 and type = 'P')
  781.       drop procedure sp_vupgrade_distdb
  782.  
  783. if exists (select * from sysobjects 
  784.         where name = 'sp_vupgrade_replmsdb' 
  785.                 and type = 'P')
  786.       drop procedure sp_vupgrade_replmsdb
  787.  
  788. if exists (select * from sysobjects 
  789.         where name = 'sp_restoredbreplication' 
  790.                 and type = 'P')
  791.       drop procedure sp_restoredbreplication
  792.  
  793. if exists (select * from sysobjects 
  794.         where name = 'sp_MSget_publisher_rpc' 
  795.                 and type = 'P')
  796.       drop procedure sp_MSget_publisher_rpc
  797.  
  798. if exists (select * from sysobjects 
  799.         where name = 'sp_link_publication' 
  800.                 and type = 'P')
  801.       drop procedure sp_link_publication
  802.  
  803. if exists (select * from sysobjects 
  804.         where name = 'sp_MS_replication_installed' 
  805.                 and type = 'P')
  806.       drop procedure sp_MS_replication_installed
  807.  
  808. if exists (select * from sysobjects 
  809.         where name = 'sp_MSunc_to_drive' 
  810.                 and type = 'P')
  811.       drop procedure sp_MSunc_to_drive
  812.  
  813. if exists (select * from sysobjects 
  814.         where name = 'sp_MSdrop_object' 
  815.                 and type = 'P')
  816.       drop procedure sp_MSdrop_object
  817.  
  818. if exists (select * from sysobjects 
  819.         where name = 'sp_MSregistersubscription' 
  820.                 and type = 'P')
  821.       drop procedure sp_MSregistersubscription
  822.  
  823. if exists (select * from sysobjects 
  824.         where name = 'sp_MSunregistersubscription' 
  825.                 and type = 'P')
  826.       drop procedure sp_MSunregistersubscription
  827.  
  828. if exists (select * from sysobjects 
  829.         where name = 'sp_MSsubscription_enabled_for_syncmgr' 
  830.                 and type = 'P')
  831.       drop procedure sp_MSsubscription_enabled_for_syncmgr
  832.  
  833. if exists (select * from sysobjects 
  834.         where name = 'sp_MSrepl_linkedservers_rowset' 
  835.                 and type = 'P')
  836.       drop procedure sp_MSrepl_linkedservers_rowset
  837.  
  838. if exists (select * from sysobjects 
  839.         where name = 'sp_MSrepl_isdbowner' 
  840.                 and type = 'P')
  841.       drop procedure sp_MSrepl_isdbowner
  842.  
  843. if exists (select * from sysobjects 
  844.         where name = 'sp_MSget_qualified_name' 
  845.                 and type = 'P')
  846.       drop procedure sp_MSget_qualified_name
  847.  
  848. if exists (select * from sysobjects 
  849.         where name = 'sp_MSscript_pkvar_assignment' 
  850.                 and type = 'P')
  851.       drop procedure sp_MSscript_pkvar_assignment
  852. go
  853.  
  854. if exists (select * from sysobjects 
  855.         where name = 'sp_MSget_jobstate' 
  856.                 and type = 'P')
  857.       drop procedure sp_MSget_jobstate
  858.  
  859. go
  860.  
  861. if exists (select * from sysobjects 
  862.         where name = 'sp_browsemergesnapshotfolder' 
  863.                 and type = 'P')
  864.       drop procedure sp_browsemergesnapshotfolder
  865. go
  866.  
  867. if exists (select * from sysobjects 
  868.         where name = 'sp_browsesnapshotfolder' 
  869.                 and type = 'P')
  870.       drop procedure sp_browsesnapshotfolder
  871. go
  872.  
  873. if exists (select * from sysobjects 
  874.         where name = 'sp_MScopysnapshot' 
  875.                 and type = 'P')
  876.       drop procedure sp_MScopysnapshot
  877. go
  878.  
  879. if exists (select * from sysobjects 
  880.         where name = 'sp_copymergesnapshot' 
  881.                 and type = 'P')
  882.       drop procedure sp_copymergesnapshot
  883. go
  884.  
  885. if exists (select * from sysobjects 
  886.         where name = 'sp_copysnapshot' 
  887.                 and type = 'P')
  888.       drop procedure sp_copysnapshot
  889. go
  890.  
  891. if exists (select * from sysobjects 
  892.         where name = 'sp_getsubscriptiondtspackagename' 
  893.                 and type = 'P')
  894.       drop procedure sp_getsubscriptiondtspackagename
  895. go
  896.  
  897.  
  898. if exists (select * from sysobjects
  899.     where type = 'P '
  900.             and name = 'sp_MSget_publication_from_taskname')
  901.     drop procedure sp_MSget_publication_from_taskname
  902. go
  903.  
  904. if exists (select * from sysobjects
  905.     where type = 'P '
  906.             and name = 'sp_MSrepl_check_server')
  907.     drop procedure sp_MSrepl_check_server
  908. go
  909.  
  910. if exists (select * from sysobjects
  911.     where type = 'P '
  912.             and name = 'sp_MSreset_synctran_bit')
  913.     drop procedure sp_MSreset_synctran_bit
  914. go
  915.  
  916. if exists (select * from sysobjects
  917.     where type = 'P '
  918.             and name = 'sp_MSreset_queue')
  919.     drop procedure sp_MSreset_queue
  920. go
  921.  
  922. if exists (select * from sysobjects
  923.     where type = 'P '
  924.             and name = 'sp_MSreset_queued_reinit')
  925.     drop procedure sp_MSreset_queued_reinit
  926. go
  927.  
  928. if exists (select * from sysobjects
  929.     where type = 'P '
  930.             and name = 'sp_MSinit_subscription_agent')
  931.     drop procedure sp_MSinit_subscription_agent
  932. go
  933.  
  934. if exists (select * from sysobjects
  935.     where type = 'P '
  936.             and name = 'sp_MSupdatelastsyncinfo')
  937.     drop procedure sp_MSupdatelastsyncinfo
  938. go
  939.  
  940. if exists (select * from sysobjects
  941.     where type = 'P '
  942.             and name = 'sp_MSget_attach_state')
  943.     drop procedure sp_MSget_attach_state
  944. go
  945.  
  946. if exists (select * from sysobjects
  947.     where type = 'P '
  948.             and name = 'sp_MSreset_attach_state')
  949.     drop procedure sp_MSreset_attach_state
  950. go
  951.  
  952. if exists (select * from sysobjects
  953.     where type = 'P'
  954.             and name = 'sp_replicationdboption')
  955.     drop procedure sp_replicationdboption
  956.  
  957. if exists (select * from sysobjects
  958.     where type = 'P '
  959.             and name = 'sp_MSset_subscription_properties')
  960.     drop procedure sp_MSset_subscription_properties
  961. go
  962.  
  963. if exists (select * from sysobjects
  964.     where type = 'P '
  965.             and name = 'sp_MSset_sub_guid')
  966.     drop procedure sp_MSset_sub_guid
  967. go
  968.  
  969. if exists (select * from sysobjects
  970.     where type = 'P '
  971.             and name = 'sp_MSscript_trigger_version_updates')
  972.     drop procedure sp_MSscript_trigger_version_updates
  973. go
  974.  
  975. if exists (select * from sysobjects
  976.     where type = 'P '
  977.             and name = 'sp_MSget_load_hint')
  978.     drop procedure sp_MSget_load_hint
  979. go
  980.  
  981. if exists (select * from sysobjects
  982.     where type in ('P ') 
  983.         and name = 'sp_repladdcolumn')
  984.     drop procedure sp_repladdcolumn
  985. go
  986. if exists (select * from sysobjects
  987.     where type in ('P ') 
  988.         and name = 'sp_MSverifytranfilter')
  989.     drop procedure sp_MSverifytranfilter
  990. go
  991.  
  992. if exists (select * from sysobjects
  993.     where type in ('P ') 
  994.         and name = 'sp_repldropcolumn')
  995.     drop procedure sp_repldropcolumn
  996. go
  997.  
  998. if exists (select * from sysobjects
  999.     where type = 'P '
  1000.             and name = 'sp_MSrepl_validate_dts_package')
  1001.     drop procedure sp_MSrepl_validate_dts_package
  1002. go
  1003.  
  1004. if exists (select * from sysobjects
  1005.      where type = 'P '
  1006.             and name = 'sp_MSagent_access_check')
  1007.      drop procedure sp_MSagent_access_check
  1008. go
  1009.  
  1010. if exists (select * from sysobjects
  1011.      where type = 'P '
  1012.             and name = 'sp_enableagentoffload')
  1013.      drop procedure sp_enableagentoffload
  1014. go
  1015.  
  1016. if exists (select * from sysobjects
  1017.      where type = 'P '
  1018.             and name = 'sp_disableagentoffload')
  1019.      drop procedure sp_disableagentoffload
  1020. go
  1021.  
  1022. if exists (select * from sysobjects
  1023.      where type = 'P '
  1024.             and name = 'sp_getagentoffloadinfo')
  1025.      drop procedure sp_getagentoffloadinfo
  1026. go
  1027.  
  1028. if exists (select * from sysobjects
  1029.      where type = 'P '
  1030.             and name = 'sp_copysubscription')
  1031.      drop procedure sp_copysubscription
  1032. go
  1033.  
  1034. if exists (select * from sysobjects
  1035.      where type = 'P '
  1036.             and name = 'sp_attachsubscription')
  1037.      drop procedure sp_attachsubscription
  1038. go
  1039.  
  1040. if exists (select * from sysobjects
  1041.      where type = 'P '
  1042.             and name = 'sp_MSget_file_existence')
  1043.      drop procedure sp_MSget_file_existence
  1044. go
  1045.  
  1046. if exists (select * from sysobjects
  1047.      where type = 'P '
  1048.             and name = 'sp_MSrestore_sub')
  1049.      drop procedure sp_MSrestore_sub
  1050. go
  1051.  
  1052. if exists (select * from sysobjects
  1053.      where type = 'P '
  1054.             and name = 'sp_MSrestore_sub_tran')
  1055.      drop procedure sp_MSrestore_sub_tran
  1056. go
  1057.  
  1058. if exists (select * from sysobjects
  1059.      where type = 'P '
  1060.             and name = 'sp_MSrestore_sub_merge')
  1061.      drop procedure sp_MSrestore_sub_merge
  1062. go
  1063.  
  1064. if exists (select * from sysobjects
  1065.      where type = 'P'
  1066.             and name = 'sp_MSsub_check_identity')
  1067.      drop procedure sp_MSsub_check_identity
  1068. go
  1069.  
  1070. if exists (select * from sysobjects
  1071.      where type = 'P'
  1072.             and name = 'sp_MSsub_cleanup_orphans')
  1073.      drop procedure sp_MSsub_cleanup_orphans
  1074. go
  1075.  
  1076. if exists (select * from sysobjects
  1077.      where type = 'P'
  1078.             and name = 'sp_MSsub_cleanup_prop_table')
  1079.      drop procedure sp_MSsub_cleanup_prop_table
  1080. go
  1081.  
  1082. if exists (select * from sysobjects
  1083.      where type = 'P'
  1084.             and name = 'sp_MSreseed')
  1085.      drop procedure sp_MSreseed
  1086. go
  1087.  
  1088. if exists (select * from sysobjects
  1089.      where type = 'P'
  1090.             and name = 'sp_MSsub_set_identity')
  1091.      drop procedure sp_MSsub_set_identity
  1092. go
  1093.  
  1094. if exists (select * from sysobjects
  1095.      where type = 'P '
  1096.             and name = 'sp_MSprepare_sub_for_detach')
  1097.      drop procedure sp_MSprepare_sub_for_detach
  1098. go
  1099.  
  1100. if exists (select * from sysobjects
  1101.      where type = 'P '
  1102.             and name = 'sp_MSadd_compensating_cmd')
  1103.      drop procedure sp_MSadd_compensating_cmd
  1104. go
  1105.  
  1106. if exists (select * from sysobjects
  1107.      where type = 'FN'
  1108.             and name = 'fn_varbintohexstr')
  1109.      drop function fn_varbintohexstr
  1110. go
  1111.  
  1112. if exists (select * from sysobjects
  1113.      where type = 'FN'
  1114.             and name = 'fn_varbintohexsubstring')
  1115.      drop function fn_varbintohexsubstring
  1116. go
  1117.  
  1118. if exists ( select * from sysobjects 
  1119.     where type = 'FN' 
  1120.             and name = 'fn_MSsharedversion' )
  1121.     drop function fn_MSsharedversion
  1122. go
  1123.  
  1124. if exists ( select * from sysobjects 
  1125.     where type = 'P' 
  1126.             and name = 'sp_MSgettools_path' )
  1127.     drop procedure sp_MSgettools_path
  1128. go
  1129.  
  1130. if exists ( select * from sysobjects 
  1131.     where type = 'P' 
  1132.             and name = 'sp_MSget_setup_paths' )
  1133.     drop procedure sp_MSget_setup_paths
  1134. go
  1135.  
  1136. if exists (select * from sysobjects where
  1137.    name = 'sp_MSaddoffloadparameter' and type = 'P')
  1138.       drop procedure sp_MSaddoffloadparameter
  1139.  
  1140. if exists (select * from sysobjects where
  1141.    name = 'sp_MSremoveoffloadparameter' and type = 'P')
  1142.       drop procedure sp_MSremoveoffloadparameter 
  1143. go
  1144.  
  1145. if exists (select * from sysobjects where
  1146.    name = 'sp_MSsendtosqlqueue' and type = 'P')
  1147.       drop procedure sp_MSsendtosqlqueue 
  1148. go
  1149.  
  1150. if exists (select * from sysobjects
  1151.     where type = 'P'
  1152.            and name = 'sp_MSdropfkreferencingarticle')
  1153.     drop procedure sp_MSdropfkreferencingarticle
  1154. go
  1155.  
  1156. if exists (select * from sysobjects
  1157.      where type = 'FN'
  1158.             and name = 'fn_MSgensqescstr')
  1159.      drop function fn_MSgensqescstr
  1160. go
  1161.  
  1162. if exists (select * from sysobjects
  1163.     where type = 'P'
  1164.             and name = 'sp_MSestimatesnapshotworkload')
  1165.     drop procedure sp_MSestimatesnapshotworkload
  1166. go
  1167.  
  1168. if exists (select * from sysobjects
  1169.     where type = 'P'
  1170.             and name = 'sp_MSestimatemergesnapshotworkload')
  1171.     drop procedure sp_MSestimatemergesnapshotworkload
  1172. go
  1173.  
  1174. if exists (select * from sysobjects
  1175.     where type = 'P'
  1176.             and name = 'sp_resyncmergesubscription')
  1177.     drop procedure sp_resyncmergesubscription
  1178. go
  1179.  
  1180. if exists (select * from sysobjects
  1181.     where type = 'P'
  1182.             and name = 'sp_MSinstance_qv')
  1183.     drop procedure sp_MSinstance_qv
  1184.  
  1185. if exists (select * from sysobjects
  1186.     where type = 'P'
  1187.             and name = 'sp_MSget_shared_agent')
  1188.     drop procedure sp_MSget_shared_agent
  1189.  
  1190.  
  1191. if exists (select * from sysobjects 
  1192.     where type = 'P'
  1193.             and name = 'sp_MSgetlastupdatedtime')
  1194.     drop procedure sp_MSgetlastupdatedtime
  1195.     
  1196. if exists (select * from sysobjects
  1197.     where type = 'P'
  1198.             and name = 'sp_MSgettranlastupdatedtime')
  1199.     drop procedure sp_MSgettranlastupdatedtime
  1200.  
  1201.  
  1202. if exists (select * from sysobjects
  1203.     where type = 'P'
  1204.             and name = 'sp_MSgetmergelastupdatedtime')
  1205.     drop procedure sp_MSgetmergelastupdatedtime
  1206. go
  1207.  
  1208. if exists (select * from sysobjects
  1209.     where type = 'P'
  1210.             and name = 'sp_MSrepl_backup_start')
  1211.     drop procedure sp_MSrepl_backup_start
  1212. go
  1213.  
  1214. if exists (select * from sysobjects
  1215.     where type = 'P'
  1216.             and name = 'sp_MSrepl_backup_complete')
  1217.     drop procedure sp_MSrepl_backup_complete
  1218. go
  1219.  
  1220. if exists (select * from sysobjects
  1221.     where type = 'P'
  1222.             and name = 'sp_MSreplcheckoffloadserver')
  1223.     drop procedure sp_MSreplcheckoffloadserver
  1224.  
  1225. if exists ( select * from sysobjects
  1226.     where type = 'P ' and name = 'sp_addscriptexec' )
  1227.     drop procedure sp_addscriptexec    
  1228.  
  1229. if exists ( select * from sysobjects
  1230.     where type = 'P ' and name = 'sp_MSmergeupdatelastsyncinfo' )
  1231.     drop procedure sp_MSmergeupdatelastsyncinfo    
  1232. go
  1233.  
  1234. if exists ( select * from sysobjects
  1235.     where type = 'P ' and name = 'sp_MSdroparticleconstraints' )
  1236.     drop procedure sp_MSdroparticleconstraints
  1237.  
  1238. go
  1239.  
  1240. if exists ( select * from sysobjects
  1241.     where type = 'FN'
  1242.     and name = 'fn_replquotename' )
  1243.     drop function system_function_schema.fn_replquotename
  1244.  
  1245. if exists ( select * from sysobjects
  1246.     where type = 'FN'
  1247.     and name = 'fn_repladjustcolumnmap' )
  1248.     drop function system_function_schema.fn_repladjustcolumnmap
  1249.  
  1250. if exists ( select * from sysobjects
  1251.     where type = 'FN'
  1252.     and name = 'fn_generateparameterpattern' )
  1253.     drop function system_function_schema.fn_generateparameterpattern
  1254.  
  1255. if exists ( select * from sysobjects
  1256.     where type = 'FN'
  1257.         and name = 'fn_removeparameterwithargument' )
  1258.     drop function system_function_schema.fn_removeparameterwithargument
  1259.  
  1260. if exists ( select * from sysobjects
  1261.     where type = 'FN'
  1262.     and name = 'fn_updateparameterwithargument' )
  1263.     drop function system_function_schema.fn_updateparameterwithargument
  1264.  
  1265. if exists ( select * from sysobjects
  1266.     where type = 'FN'
  1267.     and name = 'fn_skipparameterargument' )
  1268.     drop function system_function_schema.fn_skipparameterargument
  1269.  
  1270. if exists ( select * from sysobjects
  1271.     where type = 'FN'
  1272.         and name = 'fn_chariswhitespace' )
  1273.     drop function system_function_schema.fn_chariswhitespace
  1274.  
  1275. if exists ( select * from sysobjects
  1276.     where type = 'FN'
  1277.         and name = 'fn_replmakestringliteral' )
  1278.     drop function system_function_schema.fn_replmakestringliteral
  1279.  
  1280. if exists ( select * from sysobjects
  1281.     where type = 'FN'
  1282.     and name = 'fn_replprepadbinary8' )
  1283.    drop function system_function_schema.fn_replprepadbinary8
  1284.  
  1285. if exists ( select * from sysobjects
  1286.     where type = 'FN'
  1287.     and name = 'fn_replgetbinary8lodword' )
  1288.     drop function system_function_schema.fn_replgetbinary8lodword
  1289.  
  1290. if exists ( select * from sysobjects
  1291.     where type = 'P'
  1292.     and name = 'sp_MSacquireserverresourcefordynamicsnapshot')
  1293.     drop procedure sp_MSacquireserverresourcefordynamicsnapshot
  1294. if exists ( select * from sysobjects
  1295.     where type = 'FN'
  1296.     and name = 'fn_repluniquename' )
  1297.     drop function system_function_schema.fn_repluniquename
  1298.  
  1299. if exists (select * from sysobjects 
  1300.     where type = 'P'
  1301.             and name = 'sp_MSsetcontext_replagent')
  1302.     drop procedure sp_MSsetcontext_replagent
  1303.  
  1304. if exists ( select * from sysobjects
  1305.     where type = 'FN'
  1306.     and name = 'fn_isreplmergeagent' )
  1307.     drop function dbo.fn_isreplmergeagent 
  1308.  
  1309. if exists (select * from sysobjects 
  1310.     where type = 'FN'
  1311.     and name = N'fn_replinttobitstring' )
  1312.     drop function system_function_schema.fn_replinttobitstring
  1313.  
  1314. if exists (select * from sysobjects
  1315.     where type = 'FN'
  1316.     and name = N'fn_replbitstringtoint' )
  1317.     drop function system_function_schema.fn_replbitstringtoint
  1318.  
  1319. if exists (select * from sysobjects
  1320.     where type = 'FN'
  1321.     and name = N'fn_replrotr' )
  1322.     drop function system_function_schema.fn_replrotr
  1323.  
  1324. if exists (select * from sysobjects
  1325.     where type = 'FN'
  1326.     and name = N'fn_replgenerateshorterfilenameprefix' )
  1327.     drop function system_function_schema.fn_replgenerateshorterfilenameprefix
  1328.  
  1329. if exists (select * from sysobjects 
  1330.     where type = 'FN'
  1331.     and name = N'fn_replcomposepublicationsnapshotfolder' )
  1332.     drop function system_function_schema.fn_replcomposepublicationsnapshotfolder
  1333.  
  1334. if exists (select * from sysobjects
  1335.     where type = 'FN'
  1336.     and name = N'fn_repltrimleadingzerosinhexstr' )
  1337.     drop function system_function_schema.fn_repltrimleadingzerosinhexstr
  1338. go
  1339.  
  1340. use master
  1341. go
  1342.  
  1343. IF EXISTS ( SELECT * FROM sysobjects WHERE uid = USER_ID('system_function_schema') 
  1344.     AND name = 'fn_serverid' )
  1345. DROP FUNCTION system_function_schema.fn_serverid
  1346. go
  1347.  
  1348. sp_addextendedproc 'xp_mergexpusage', 'xprepl.dll'
  1349. go
  1350.  
  1351. grant exec on xp_mergexpusage to public
  1352. go
  1353.  
  1354. if exists (select * from sysobjects
  1355.         where name = 'xp_showlineage')
  1356.     execute dbo.sp_dropextendedproc 'xp_showlineage'
  1357. go
  1358.  
  1359. sp_addextendedproc 'xp_showlineage', 'xprepl.dll'
  1360. go
  1361.  
  1362. grant exec on xp_showlineage to public
  1363. go
  1364.  
  1365. if exists (select * from sysobjects
  1366.         where name = 'xp_mergelineages' and xtype = 'X')
  1367.     execute dbo.sp_dropextendedproc 'xp_mergelineages'
  1368. go
  1369.  
  1370. sp_addextendedproc 'xp_mergelineages', 'xprepl.dll'
  1371. go
  1372.  
  1373. grant exec on xp_mergelineages to public
  1374. go
  1375.  
  1376. if exists (select * from sysobjects    where name = 'xp_updatelineage' and xtype = 'X')
  1377.     execute dbo.sp_dropextendedproc 'xp_updatelineage'
  1378. go
  1379.  
  1380. if exists (select * from sysobjects
  1381.         where name = 'xp_mapdown_bitmap')
  1382.     execute dbo.sp_dropextendedproc 'xp_mapdown_bitmap'
  1383. go
  1384.  
  1385. sp_addextendedproc 'xp_mapdown_bitmap', 'xprepl.dll'
  1386. go
  1387.  
  1388. grant exec on xp_mapdown_bitmap to public
  1389. go
  1390.  
  1391. if exists (select * from sysobjects
  1392.         where name = 'xp_ORbitmap')
  1393.     execute dbo.sp_dropextendedproc 'xp_ORbitmap'
  1394. go
  1395. sp_addextendedproc 'xp_ORbitmap', 'xprepl.dll'
  1396. go
  1397. grant exec on xp_ORbitmap to public
  1398. go
  1399.  
  1400. if exists (select * from sysobjects
  1401.         where name = 'xp_proxiedmetadata')
  1402.     execute dbo.sp_dropextendedproc 'xp_proxiedmetadata'
  1403. go
  1404.  
  1405. sp_addextendedproc 'xp_proxiedmetadata', 'xprepl.dll'
  1406. go
  1407.  
  1408. grant exec on xp_proxiedmetadata to public
  1409. go
  1410.  
  1411. if exists (select * from sysobjects    where name = 'xp_initcolvs' and xtype = 'X')
  1412.     execute dbo.sp_dropextendedproc 'xp_initcolvs'
  1413. go
  1414.  
  1415. if exists (select * from sysobjects    where name = 'xp_updatecolvbm' and xtype = 'X')
  1416.     execute dbo.sp_dropextendedproc 'xp_updatecolvbm'
  1417. go
  1418.  
  1419. if exists (select * from sysobjects
  1420.         where name = 'xp_showcolv')
  1421.     execute dbo.sp_dropextendedproc 'xp_showcolv'
  1422. go
  1423.  
  1424. sp_addextendedproc 'xp_showcolv', 'xprepl.dll'
  1425. go
  1426.  
  1427. grant exec on xp_showcolv to public
  1428. go
  1429.  
  1430. if exists (select * from sysobjects
  1431.         where name = 'xp_execresultset')
  1432.     execute dbo.sp_dropextendedproc 'xp_execresultset'
  1433. go
  1434.  
  1435. sp_addextendedproc 'xp_execresultset', 'xprepl.dll'
  1436. go
  1437.  
  1438. grant exec on xp_execresultset to public
  1439. go
  1440.  
  1441. if exists (select * from sysobjects
  1442.         where name = 'xp_varbintohexstr')
  1443.     execute dbo.sp_dropextendedproc 'xp_varbintohexstr'
  1444. go
  1445.  
  1446. sp_addextendedproc 'xp_varbintohexstr', 'xprepl.dll'
  1447. go
  1448.  
  1449. grant exec on xp_varbintohexstr to public
  1450. go
  1451.  
  1452. if exists (select * from sysobjects
  1453.         where name = 'xp_intersectbitmaps')
  1454.     execute dbo.sp_dropextendedproc 'xp_intersectbitmaps'
  1455. go
  1456.  
  1457. sp_addextendedproc 'xp_intersectbitmaps', 'xprepl.dll'
  1458. go
  1459.  
  1460. grant exec on xp_intersectbitmaps to public
  1461. go
  1462.  
  1463. if exists (select * from sysobjects
  1464.         where name = 'xp_displayparamstmt')
  1465.     execute dbo.sp_dropextendedproc 'xp_displayparamstmt'
  1466. go
  1467.  
  1468. sp_addextendedproc 'xp_displayparamstmt', 'xprepl.dll'
  1469. go
  1470.  
  1471. grant exec on xp_displayparamstmt to public
  1472. go
  1473.  
  1474.  
  1475. if exists (select * from sysobjects
  1476.         where name = 'xp_printstatements')
  1477.     execute dbo.sp_dropextendedproc 'xp_printstatements'
  1478. go
  1479.  
  1480. sp_addextendedproc 'xp_printstatements', 'xprepl.dll'
  1481. go
  1482.  
  1483. grant exec on xp_printstatements to public
  1484. go
  1485.  
  1486. if exists (select * from sysobjects
  1487.         where name = 'xp_createqueue')
  1488.     execute dbo.sp_dropextendedproc 'xp_createqueue'
  1489. go
  1490.  
  1491. sp_addextendedproc 'xp_createqueue', 'xpqueue.dll'
  1492. go
  1493.  
  1494. if exists (select * from sysobjects
  1495.         where name = 'xp_createprivatequeue')
  1496.     execute dbo.sp_dropextendedproc 'xp_createprivatequeue'
  1497.  
  1498. exec sp_addextendedproc 'xp_createprivatequeue', 'xpqueue.dll'
  1499. go
  1500.  
  1501. if exists (select * from sysobjects
  1502.         where name = 'xp_deletequeue')
  1503.     execute dbo.sp_dropextendedproc 'xp_deletequeue'
  1504. go
  1505.  
  1506. sp_addextendedproc 'xp_deletequeue', 'xpqueue.dll'
  1507. go
  1508.  
  1509.  
  1510. if exists (select * from sysobjects
  1511.         where name = 'xp_deleteprivatequeue')
  1512.     execute dbo.sp_dropextendedproc 'xp_deleteprivatequeue'
  1513.  
  1514. exec sp_addextendedproc 'xp_deleteprivatequeue', 'xpqueue.dll'
  1515. go
  1516.  
  1517. if exists (select * from sysobjects
  1518.         where name = 'sp_replsendtoqueue')
  1519.     execute dbo.sp_dropextendedproc 'sp_replsendtoqueue'
  1520. go
  1521.  
  1522. sp_addextendedproc 'sp_replsendtoqueue', 'sp_replsendtoqueue extended proc'
  1523. go
  1524.  
  1525. grant exec on sp_replsendtoqueue to public
  1526. go
  1527.  
  1528. if exists (select * from sysobjects
  1529.         where name = 'sp_replwritetovarbin')
  1530.     execute dbo.sp_dropextendedproc 'sp_replwritetovarbin'
  1531. go
  1532.  
  1533. sp_addextendedproc 'sp_replwritetovarbin', 'sp_replwritetovarbin extended proc'
  1534. go
  1535.  
  1536. grant exec on sp_replwritetovarbin to public
  1537. go
  1538.  
  1539. if exists (select * from sysobjects
  1540.         where name = 'xp_resetqueue')
  1541.     execute dbo.sp_dropextendedproc 'xp_resetqueue'
  1542. go
  1543.  
  1544. sp_addextendedproc 'xp_resetqueue', 'xpqueue.dll'
  1545. go
  1546.  
  1547. if exists (select * from sysobjects
  1548.         where name = 'xp_peekqueue')
  1549.     execute dbo.sp_dropextendedproc 'xp_peekqueue'
  1550. go
  1551.  
  1552. sp_addextendedproc 'xp_peekqueue', 'xpqueue.dll'
  1553. go
  1554.  
  1555. grant exec on xp_peekqueue to public
  1556. go
  1557.  
  1558. if exists (select * from sysobjects
  1559.         where name = 'xp_controlqueueservice')
  1560.     execute dbo.sp_dropextendedproc 'xp_controlqueueservice'
  1561. go
  1562.  
  1563. sp_addextendedproc 'xp_controlqueueservice', 'xpqueue.dll'
  1564. go
  1565.  
  1566. if exists (select * from sysobjects
  1567.         where name = 'xp_displayqueuemesgs')
  1568.     execute dbo.sp_dropextendedproc 'xp_displayqueuemesgs'
  1569. go
  1570.  
  1571. sp_addextendedproc 'xp_displayqueuemesgs', 'xpqueue.dll'
  1572. go
  1573.  
  1574. if exists (select * from sysobjects
  1575.         where name = 'xp_decodequeuecmd')
  1576.     execute dbo.sp_dropextendedproc 'xp_decodequeuecmd'
  1577. go
  1578.  
  1579. sp_addextendedproc 'xp_decodequeuecmd', 'xpqueue.dll'
  1580. go
  1581.  
  1582. if exists (select * from sysobjects
  1583.         where name = 'xp_readpkfromqueue')
  1584.     execute dbo.sp_dropextendedproc 'xp_readpkfromqueue'
  1585. go
  1586.  
  1587. sp_addextendedproc 'xp_readpkfromqueue', 'xpqueue.dll'
  1588. go
  1589.  
  1590. if exists (select * from sysobjects
  1591.         where name = 'xp_readpkfromvarbin')
  1592.     execute dbo.sp_dropextendedproc 'xp_readpkfromvarbin'
  1593. go
  1594.  
  1595. sp_addextendedproc 'xp_readpkfromvarbin', 'xpqueue.dll'
  1596. go
  1597.  
  1598. /*
  1599. ** Add xp_makecab extended procedure
  1600. */
  1601.  
  1602. if exists (select * from sysobjects
  1603.         where type = 'X'
  1604.             and name = 'xp_makecab')
  1605.     exec dbo.sp_dropextendedproc 'xp_makecab'
  1606. go
  1607.  
  1608. sp_addextendedproc 'xp_makecab', 'xprepl.dll'
  1609. go
  1610. exec dbo.sp_MS_marksystemobject xp_makecab
  1611. go
  1612.  
  1613. /*
  1614. ** Add xp_unpackcab extended procedure
  1615. */
  1616.  
  1617. if exists (select * from sysobjects
  1618.         where type = 'X'
  1619.             and name = 'xp_unpackcab')
  1620.     exec dbo.sp_dropextendedproc 'xp_unpackcab'
  1621. go
  1622.  
  1623. sp_addextendedproc 'xp_unpackcab', 'xprepl.dll'
  1624. go
  1625. exec dbo.sp_MS_marksystemobject xp_unpackcab
  1626. go
  1627.  
  1628. /* Create table dbo.MSreplication_options */
  1629. IF NOT EXISTS (SELECT * FROM sysobjects WHERE name = 'MSreplication_options'
  1630.     and type = 'U')
  1631. BEGIN
  1632.     raiserror('Creating procedure Creating table MSreplication_options',0,1)
  1633.     
  1634.  
  1635.     CREATE TABLE dbo.MSreplication_options 
  1636.     (
  1637.     optname            sysname NOT NULL,
  1638.     value            bit NOT NULL,
  1639.     major_version    int NOT NULL,
  1640.     minor_version    int NOT NULL,
  1641.     revision        int NOT NULL,
  1642.     install_failures int NOT NULL
  1643.     )
  1644. END
  1645. GO
  1646.  
  1647. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'transactional')
  1648.     INSERT INTO MSreplication_options VALUES
  1649.         ('transactional',0,0,0,0,0)
  1650. IF NOT EXISTS (SELECT * FROM MSreplication_options WHERE optname = 'merge')
  1651.     INSERT INTO MSreplication_options VALUES
  1652.         ('merge',0,0,0,0,0)
  1653. GO
  1654.  
  1655. print ''
  1656. print 'Creating function fn_repltrimleadingzerosinhexstr'
  1657. go
  1658. -- 
  1659. -- Name: fn_repltrimleadingzerosinhexstr
  1660. --
  1661. -- Description: This function is used for trimming the leading zeros 
  1662. --              of a 32-bit hexadecimal string. For example,
  1663. --              select fn_repltrimleadingzerosinhexstr('0000abcd') would 
  1664. --              yield 'abcd'. A notable special case would be select
  1665. --              fn_repltrimleadingzerosinhexstr('00000000') which yields
  1666. --              the string '0' instead of ''.
  1667. --
  1668. -- Parameter:   @hexstr  nchar(8) - @hexstr is expected to be a full 
  1669. --              hexadecimal representation of a 32-bit integer without the
  1670. --              0x prefix
  1671. --
  1672. -- Notes: 
  1673. --
  1674. -- Returns:     nvarchar(8)
  1675. -- 
  1676. -- Security:    Execute permission of this function is granted to public.
  1677. --
  1678. create function system_function_schema.fn_repltrimleadingzerosinhexstr (
  1679.     @hexstr nchar(8)
  1680.     ) returns nvarchar(8)
  1681. as
  1682. begin
  1683.     declare @trimmed_hexstr nvarchar(8),
  1684.             @i int    
  1685.     select @i = 1
  1686.     while @i < 8
  1687.     begin
  1688.         if substring(@hexstr,@i,1) <> N'0'
  1689.             break;
  1690.         select @i = @i + 1
  1691.     end    
  1692.     select @trimmed_hexstr = substring(@hexstr,@i,8-@i+1)
  1693.     return @trimmed_hexstr
  1694. end
  1695. go
  1696. grant execute on system_function_schema.fn_repltrimleadingzerosinhexstr to public
  1697.  
  1698. print ''
  1699. print 'Creating function fn_replinttobitstring'
  1700. go
  1701. --
  1702. -- Name: fn_replinttobitstring
  1703. -- 
  1704. -- Description: This function returns the bit pattern in string format for 
  1705. --              the specified 32-bit integer. For example, select 
  1706. --              fn_replinttobitstring(0x80000001) would yield
  1707. --              '10000000000000000000000000000001'
  1708. --
  1709. -- Parameter:   @number int
  1710. --
  1711. -- Returns:     char(32)
  1712. --
  1713. -- Security:    Execute permission of this function is granted to public.
  1714. --
  1715. create function system_function_schema.fn_replinttobitstring(
  1716.     @number int
  1717.     ) returns char(32)
  1718. as
  1719. begin
  1720.  
  1721.     declare @bitstring nvarchar(32)
  1722.  
  1723.     if (@number & 0x80000000) <> 0 select @bitstring = '1' else select @bitstring = '0'
  1724.     if (@number & 0x40000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1725.     if (@number & 0x20000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1726.     if (@number & 0x10000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1727.     if (@number & 0x08000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1728.     if (@number & 0x04000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1729.     if (@number & 0x02000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1730.     if (@number & 0x01000000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1731.     if (@number & 0x00800000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1732.     if (@number & 0x00400000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1733.     if (@number & 0x00200000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1734.     if (@number & 0x00100000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1735.     if (@number & 0x00080000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1736.     if (@number & 0x00040000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1737.     if (@number & 0x00020000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1738.     if (@number & 0x00010000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1739.     if (@number & 0x00008000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1740.     if (@number & 0x00004000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1741.     if (@number & 0x00002000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1742.     if (@number & 0x00001000) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1743.     if (@number & 0x00000800) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1744.     if (@number & 0x00000400) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1745.     if (@number & 0x00000200) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1746.     if (@number & 0x00000100) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1747.     if (@number & 0x00000080) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1748.     if (@number & 0x00000040) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1749.     if (@number & 0x00000020) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1750.     if (@number & 0x00000010) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1751.     if (@number & 0x00000008) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1752.     if (@number & 0x00000004) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1753.     if (@number & 0x00000002) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1754.     if (@number & 0x00000001) <> 0 select @bitstring = @bitstring + '1' else select @bitstring = @bitstring + '0'
  1755.  
  1756.     return @bitstring
  1757. end
  1758. go
  1759. grant execute on system_function_schema.fn_replinttobitstring to public
  1760.  
  1761. print ''
  1762. print 'Creating function fn_replbitstringtoint'
  1763. go
  1764. --
  1765. -- Name: fn_replbitstringtoint
  1766. --
  1767. -- Description: This function returns the integer value of the specified
  1768. --              32-bit bit pattern in string format.
  1769. --
  1770. -- Parameter:   @bitstring char(32)
  1771. --
  1772. -- Notes:
  1773. --
  1774. -- Returns:     int
  1775. --
  1776. -- Security:    Execute permission of this function is granted to public.
  1777. --
  1778. create function system_function_schema.fn_replbitstringtoint(
  1779.     @bitstring char(32)
  1780.     ) returns int
  1781. as
  1782. begin
  1783.     declare @number int 
  1784.     select @number = 0
  1785.     if (substring(@bitstring,1,1) = '1') select @number = @number | 0x80000000 
  1786.     if (substring(@bitstring,2,1) = '1') select @number = @number | 0x40000000 
  1787.     if (substring(@bitstring,3,1) = '1') select @number = @number | 0x20000000 
  1788.     if (substring(@bitstring,4,1) = '1') select @number = @number | 0x10000000 
  1789.     if (substring(@bitstring,5,1) = '1') select @number = @number | 0x08000000 
  1790.     if (substring(@bitstring,6,1) = '1') select @number = @number | 0x04000000 
  1791.     if (substring(@bitstring,7,1) = '1') select @number = @number | 0x02000000 
  1792.     if (substring(@bitstring,8,1) = '1') select @number = @number | 0x01000000 
  1793.     if (substring(@bitstring,9,1) = '1') select @number = @number | 0x00800000 
  1794.     if (substring(@bitstring,10,1) = '1') select @number = @number | 0x00400000 
  1795.     if (substring(@bitstring,11,1) = '1') select @number = @number | 0x00200000 
  1796.     if (substring(@bitstring,12,1) = '1') select @number = @number | 0x00100000 
  1797.     if (substring(@bitstring,13,1) = '1') select @number = @number | 0x00080000 
  1798.     if (substring(@bitstring,14,1) = '1') select @number = @number | 0x00040000 
  1799.     if (substring(@bitstring,15,1) = '1') select @number = @number | 0x00020000 
  1800.     if (substring(@bitstring,16,1) = '1') select @number = @number | 0x00010000 
  1801.     if (substring(@bitstring,17,1) = '1') select @number = @number | 0x00008000 
  1802.     if (substring(@bitstring,18,1) = '1') select @number = @number | 0x00004000 
  1803.     if (substring(@bitstring,19,1) = '1') select @number = @number | 0x00002000 
  1804.     if (substring(@bitstring,20,1) = '1') select @number = @number | 0x00001000 
  1805.     if (substring(@bitstring,21,1) = '1') select @number = @number | 0x00000800 
  1806.     if (substring(@bitstring,22,1) = '1') select @number = @number | 0x00000400 
  1807.     if (substring(@bitstring,23,1) = '1') select @number = @number | 0x00000200 
  1808.     if (substring(@bitstring,24,1) = '1') select @number = @number | 0x00000100 
  1809.     if (substring(@bitstring,25,1) = '1') select @number = @number | 0x00000080 
  1810.     if (substring(@bitstring,26,1) = '1') select @number = @number | 0x00000040 
  1811.     if (substring(@bitstring,27,1) = '1') select @number = @number | 0x00000020 
  1812.     if (substring(@bitstring,28,1) = '1') select @number = @number | 0x00000010 
  1813.     if (substring(@bitstring,29,1) = '1') select @number = @number | 0x00000008 
  1814.     if (substring(@bitstring,30,1) = '1') select @number = @number | 0x00000004 
  1815.     if (substring(@bitstring,31,1) = '1') select @number = @number | 0x00000002 
  1816.     if (substring(@bitstring,32,1) = '1') select @number = @number | 0x00000001 
  1817.     return @number
  1818. end
  1819. go
  1820. grant execute on system_function_schema.fn_replbitstringtoint to public
  1821.  
  1822. print ''
  1823. print 'Creating function fn_replrotr'
  1824. go
  1825. --
  1826. -- Name: fn_replrotr
  1827. --
  1828. -- Description: This is just a T-SQL implementation of the C function
  1829. --              _rotr().
  1830. --
  1831. -- Parameter:  @number int
  1832. --             @shift  int
  1833. --
  1834. -- Notes:      The effective shift will the positive remainder of @shift 
  1835. --             divided by 32. _rotl() can be implemented by passing in 
  1836. --             a negative shift.
  1837. --
  1838. -- Returns:    int
  1839. --
  1840. -- Security:   Execute permission of this function is granted to public.
  1841. --
  1842. create function system_function_schema.fn_replrotr(
  1843.     @number int,
  1844.     @shift int
  1845.     ) returns int
  1846. as
  1847. begin
  1848.     declare @bitstring char(32)
  1849.     select @shift = @shift % 32
  1850.     if @shift < 0
  1851.         select @shift = @shift + 32
  1852.  
  1853.     if (@shift != 0)
  1854.     begin
  1855.         select @bitstring = fn_replinttobitstring(@number)   
  1856.         select @bitstring = substring(@bitstring,32-@shift+1,@shift) + substring(@bitstring,1,32-@shift) 
  1857.         select @number = fn_replbitstringtoint(@bitstring)
  1858.     end
  1859.     return @number
  1860. end
  1861. go
  1862. grant execute on system_function_schema.fn_replrotr to public
  1863.  
  1864.  
  1865. print ''
  1866. print 'Creating function fn_replgenerateshorterfilenameprefix'
  1867. go
  1868. --
  1869. -- Name: fn_replgenerateshorterfilenameprefix
  1870. --
  1871. -- Description: This function mimics the algorithm used by the snapshot 
  1872. --              agent to shorten any overly long component of a publication
  1873. --              snapshot folder with "overly long" defined as more than
  1874. --              30 characters in length (as specified in the @truncated_len
  1875. --              parameter of this function). 
  1876. --                
  1877. -- Parameters:  @prefix nvarchar(4000)
  1878. --              @truncated_len int
  1879. --
  1880. -- Notes:
  1881. --
  1882. -- Returns: nvarchar(4000)
  1883. --
  1884. -- Security: Execute permission on this function is granted to public.
  1885. --
  1886. create function system_function_schema.fn_replgenerateshorterfilenameprefix(
  1887.     @prefix nvarchar(4000),
  1888.     @truncated_len int
  1889.     ) returns nvarchar(4000)
  1890. as
  1891. begin
  1892.     declare @HashValueIndex int,
  1893.             @HashValue int,
  1894.             @CurrentByte tinyint,
  1895.             @TruncatedString varbinary(8000),
  1896.             @i int,
  1897.             @TruncatedStringLen int,
  1898.             @prefix_to_be_returned nvarchar(4000)
  1899.  
  1900.     select @prefix_to_be_returned = @prefix
  1901.     if (len(@prefix) > @truncated_len)
  1902.     begin
  1903.         select @TruncatedString = convert(varbinary(8000),substring(@prefix,@truncated_len-8+1,len(@prefix)-@truncated_len+8))
  1904.         select @TruncatedStringLen = len(@TruncatedString)
  1905.         select @HashValue = 0
  1906.         select @i = 1
  1907.         select @HashValueIndex = 0
  1908.         while @i <= @TruncatedStringLen
  1909.         begin
  1910.             select @CurrentByte = convert(tinyint,substring(@TruncatedString,@i,1))
  1911.             select @HashValue = @HashValue ^ fn_replrotr(@CurrentByte, -(8*@HashValueIndex))
  1912.             select @HashValue = fn_replrotr(@HashValue, @HashValueIndex + 1)
  1913.             if @CurrentByte != 0
  1914.             begin
  1915.                 select @HashValueIndex = (@HashValueIndex + 1) % 4
  1916.             end
  1917.             select @i = @i + 1
  1918.         end
  1919.         select @prefix_to_be_returned = substring(@prefix,1,@truncated_len-8) 
  1920.         select @prefix_to_be_returned = @prefix_to_be_returned + lower(fn_repltrimleadingzerosinhexstr(substring(master.dbo.fn_varbintohexstr(convert(varbinary(4),@HashValue)) collate database_default,3,8)) collate database_default)
  1921.     end
  1922.     return @prefix_to_be_returned
  1923. end
  1924. go
  1925. grant execute on system_function_schema.fn_replgenerateshorterfilenameprefix to public      
  1926.  
  1927. print ''
  1928. print 'Creating function fn_replcomposepublicationsnapshotfolder'
  1929. go    
  1930. --
  1931. -- Name: fn_replcomposepublicationsnapshotfolder
  1932. --
  1933. -- Description: This mimics the algorithm used by the snapshot agent for 
  1934. --              composing the name of a publication's snapshot folder.
  1935. --
  1936. -- Parameters:  @publisher    sysname
  1937. --              @publisher_db sysname 
  1938. --              @publication  sysname
  1939. --
  1940. -- Notes: 
  1941. --
  1942. -- Returns: nvarchar(255)
  1943. --
  1944. -- Security: Execute permission of this function is granted to public.
  1945. --
  1946. create function system_function_schema.fn_replcomposepublicationsnapshotfolder(
  1947.     @publisher     sysname,
  1948.     @publisher_db  sysname,
  1949.     @publication   sysname
  1950. ) returns nvarchar(255)
  1951. as
  1952. begin
  1953.     declare @snapshot_folder_name nvarchar(255)
  1954.     
  1955.     select @snapshot_folder_name = fn_replgenerateshorterfilenameprefix(@publisher,30) collate database_default + N'_' +
  1956.                                    fn_replgenerateshorterfilenameprefix(@publisher_db,30) collate database_default + N'_' +
  1957.                                    fn_replgenerateshorterfilenameprefix(@publication,30) collate database_default
  1958.     return @snapshot_folder_name
  1959. end
  1960. go
  1961. grant execute on system_function_schema.fn_replcomposepublicationsnapshotfolder to public
  1962. go
  1963.  
  1964. --
  1965. -- Name: sp_MSdroparticleconstraints
  1966. --
  1967. -- Description: This procedure is used by the Distribution Agent to purge all
  1968. --              the existing check, PK, UK, and FK constraints on a table
  1969. --              article at the Subscriber.
  1970. --
  1971. -- Parameters:  @destination_object sysname (mandatory)
  1972. --              @destination_owner sysname (mandatory)
  1973. -- 
  1974. -- Returns: 0 - succeeded
  1975. --          1 - failed
  1976. -- 
  1977. -- Security: Procedural security check is done inside this procedure
  1978. --           to make sure that the caller is either a member of the db_owner
  1979. --           role of the subscriber database or a member of the sysadmin role
  1980. --           of the subscription server 
  1981. --
  1982. print ''
  1983. print 'Creating procedure sp_MSdroparticleconstraints'
  1984. go
  1985. create procedure dbo.sp_MSdroparticleconstraints (
  1986.     @destination_object sysname,
  1987.     @destination_owner sysname
  1988.     )
  1989. as
  1990. begin
  1991.     set nocount on
  1992.     declare @retcode      int,
  1993.             @objid        int,
  1994.             @constid      int,
  1995.             @drop_command nvarchar(4000),
  1996.             @qualified_tablename nvarchar(540),
  1997.             @publish_bit  int,
  1998.             @mergepublish_bit int
  1999.  
  2000.     
  2001.     select @retcode             = 0,
  2002.            @objid               = null,
  2003.            @constid             = null,
  2004.            @drop_command        = null,
  2005.            @qualified_tablename = null,
  2006.            @publish_bit         = 1,
  2007.            @mergepublish_bit    = 128
  2008.  
  2009.     -- Security check
  2010.     exec @retcode = sp_MSreplcheck_subscribe
  2011.     if @retcode<>0 or @@error<>0
  2012.         return 1
  2013.  
  2014.     -- Get object id of the target table
  2015.     select @objid = id 
  2016.       from sysobjects
  2017.      where name = @destination_object
  2018.        and (user_name(uid) = @destination_owner 
  2019.             or @destination_owner is null 
  2020.             or @destination_owner = N'')
  2021.  
  2022.     -- If the object is not at the subscriber, there isn't anything we 
  2023.     -- can(or need to)  do
  2024.     if @objid is null 
  2025.         return 0
  2026.  
  2027.     select @qualified_tablename = 
  2028.             N'['+replace(@destination_object,N']',N']]')+N']'
  2029.  
  2030.     if @destination_owner is not null and @destination_owner<>N''
  2031.     begin
  2032.         select @qualified_tablename = 
  2033.             N'['+replace(@destination_owner,N']',N']]')+N'].'+@qualified_tablename
  2034.     end
  2035.  
  2036.     -- Skip constraint dropping for republished article
  2037.     if exists (select * 
  2038.                  from sysobjects 
  2039.                 where id = @objid
  2040.                   and ((replinfo & @publish_bit <> 0) or
  2041.                        (replinfo & @mergepublish_bit <> 0)))
  2042.     begin
  2043.         return 0
  2044.     end
  2045.  
  2046.     declare hConst cursor local fast_forward for
  2047.      select constid 
  2048.        from sysconstraints 
  2049.       where id = @objid
  2050.       order by convert(int, objectproperty(constid,'IsForeignKey')) desc
  2051.     if @@error<>0
  2052.         return 1
  2053.  
  2054.     open hConst
  2055.     if @@error<>0
  2056.         return 1
  2057.     
  2058.     fetch hConst into @constid 
  2059.     while (@@fetch_status<>-1)
  2060.     begin
  2061.     
  2062.         if objectproperty(@constid,N'IsUniqueCnst') = 1 or
  2063.            objectproperty(@constid,N'IsPrimaryKey') = 1 or
  2064.            objectproperty(@constid,N'IsCheckCnst') = 1 or
  2065.            objectproperty(@constid,N'IsForeignKey') = 1
  2066.         begin
  2067.             select @drop_command = 
  2068.                 N'alter table '+@qualified_tablename+' drop constraint '+object_name(@constid)
  2069.             exec(@drop_command)
  2070.             if @@error <> 0
  2071.                 return 1
  2072.         end
  2073.         fetch hConst into @constid        
  2074.     end
  2075.     close hConst
  2076.     deallocate hConst
  2077.  
  2078.     return @retcode
  2079.  
  2080. end
  2081. go
  2082. exec sp_MS_marksystemobject sp_MSdroparticleconstraints
  2083. grant execute on sp_MSdroparticleconstraints to public 
  2084. --
  2085. -- Name: sp_MSacquireserverresourcefordynamicsnapshot
  2086. --
  2087. -- Description: This is a light-weight wrapper of sp_MSacuireApplicationLock
  2088. --              used by dynamic snapshot for governing the maximum number of
  2089. --              concurrent dynamic snapshot sessions for a merge publication.
  2090. --
  2091. -- Parameters: @publication sysname (mandatory)
  2092. --             @max_concurrent_dynamic_snapshots int (mandatory)
  2093. --
  2094. -- Security: Procedural security check is performed inside 
  2095. --           sp_MSacquireSlotLock to make sure that the caller is 
  2096. --           either sysadmin, db_owner, or replication agent.
  2097. --
  2098. print ''
  2099. print 'Creating procedure sp_MSacquireserverresourcefordynamicsnapshot'
  2100. go
  2101. create procedure dbo.sp_MSacquireserverresourcefordynamicsnapshot (
  2102.     @publication sysname,
  2103.     @max_concurrent_dynamic_snapshots int
  2104.     )
  2105. as
  2106. begin
  2107.     set nocount on
  2108.     declare @retcode int
  2109.     declare @pubid uniqueidentifier
  2110.     declare @process_name sysname
  2111.     select @retcode = 0
  2112.  
  2113.     if object_id('sysmergepublications') is null
  2114.     begin
  2115.         raiserror(20026, 16, -1, @publication)
  2116.         return (1) 
  2117.     end
  2118.  
  2119.     select @pubid = null
  2120.     select @pubid = pubid 
  2121.       from sysmergepublications
  2122.      where name = @publication 
  2123.        and publisher_db = db_name()
  2124.        and upper(publisher) = upper(@@servername)
  2125.              
  2126.     if @pubid is null   
  2127.     begin
  2128.         raiserror(20026, 16, -1, @publication)
  2129.         return (1) 
  2130.     end
  2131.  
  2132.     -- The following string construction will never overflow
  2133.     -- sysname
  2134.     select @process_name = N'ReplicationSnapshotAgent' + 
  2135.         convert(nvarchar(40), @pubid)     
  2136.  
  2137.     -- Acquire head of queue lock first
  2138.     exec @retcode = sp_MSacquireHeadofQueueLock
  2139.         @process_name = @process_name,
  2140.         @queue_timeout = 0,
  2141.         @no_result = 1
  2142.  
  2143.     if @@error<>0
  2144.         return (1)
  2145.  
  2146.     if @retcode<>0
  2147.         goto Failure
  2148.  
  2149.     exec @retcode = sp_MSacquireSlotLock 
  2150.         @process_name = @process_name,
  2151.         @concurrent_max = @max_concurrent_dynamic_snapshots    
  2152.     
  2153.     if @@error<>0
  2154.         return (1)
  2155.  
  2156. Failure:
  2157.  
  2158.     return @retcode
  2159. end
  2160. go
  2161. exec sp_MS_marksystemobject sp_MSacquireserverresourcefordynamicsnapshot
  2162. go
  2163. grant execute on sp_MSacquireserverresourcefordynamicsnapshot to public
  2164. go
  2165.  
  2166. -- 
  2167. -- Name: fn_replgetbinary8lodword
  2168. --
  2169. -- Description: This function will get the lower dword of
  2170. --              a given binary(8) value. For example:
  2171. --            
  2172. --              select fn_replgetbinary8lodword(0x0000000012345678)
  2173. --              will return the integer
  2174. --              0x12345678
  2175. --
  2176. -- Parameter: @binary8_value binary(8)
  2177. --
  2178. -- Returns: int
  2179. --
  2180. -- Security: Execute permission of this function is granted 
  2181. --           to public
  2182. --
  2183. print ''
  2184. print 'Creating function fn_replgetbinary8lodword'
  2185. go
  2186. create function system_function_schema.fn_replgetbinary8lodword (
  2187.     @binary8_value binary(8)
  2188.     ) returns int
  2189. as
  2190. begin
  2191.     declare @lodword int
  2192.     select @lodword = convert(int, substring(@binary8_value, 5, 4))
  2193.     return @lodword
  2194. end
  2195. go
  2196. grant execute on system_function_schema.fn_replgetbinary8lodword to public
  2197. go
  2198.  
  2199. -- 
  2200. -- Name: fn_replprepadbinary8
  2201. --
  2202. -- Description: This function is typically used by replication
  2203. --              stored procedures to add padding 0s in front
  2204. --              of a user-specified schema_option value. For
  2205. --              example:
  2206. --
  2207. --              select fn_replprepadbinary8(0x01) will return
  2208. --
  2209. --              0x0000000000000001
  2210. --
  2211. -- Parameter: @varbinary8_value varbinary(8)
  2212. --
  2213. -- Returns: binary(8) 
  2214. --              
  2215. -- Security: Execute permission of this function is granted
  2216. --           to public
  2217. --               
  2218. print ''
  2219. print 'Creating function fn_replprepadbinary8'
  2220. go
  2221. create function system_function_schema.fn_replprepadbinary8 (
  2222.     @varbinary8_value varbinary(8)
  2223.     ) returns binary(8)
  2224. as
  2225. begin
  2226.     declare @padded_value binary(8)
  2227.     select @padded_value = 
  2228.         substring(0x0000000000000000, 
  2229.                   1, 
  2230.                   8 - datalength(@varbinary8_value)) 
  2231.         + @varbinary8_value
  2232.     return @padded_value
  2233. end
  2234. go
  2235. grant execute on system_function_schema.fn_replprepadbinary8 to public
  2236. go
  2237.  
  2238. --
  2239. -- Name: fn_replmakestringliteral
  2240. --
  2241. -- Description: This is a simple helper function for generating the unicode string 
  2242. --              literal representation of a given string. For example
  2243. --              
  2244. --                  select fn_replmakestringliteral('string''literal')
  2245. -- 
  2246. --              will return
  2247. --
  2248. --                  N'string''literal'
  2249. --
  2250. -- Parameter: @string nvarchar(4000)
  2251. -- 
  2252. -- Returns: nvarchar(4000)
  2253. --
  2254. -- Security: Public access
  2255. --
  2256. raiserror('Creating function fn_replmakestringliteral', 0,1)
  2257. go
  2258. create function system_function_schema.fn_replmakestringliteral (
  2259.     @string nvarchar(4000)
  2260.     ) returns nvarchar(4000)
  2261. as
  2262. begin
  2263.     declare @string_literal nvarchar(4000)
  2264.     select @string_literal = N'N''' + replace(@string, '''', '''''') + N''''
  2265.     return @string_literal
  2266. end
  2267. go
  2268. grant execute on system_function_schema.fn_replmakestringliteral to public
  2269. go
  2270.  
  2271. -- 
  2272. -- Name: sp_MSgettranlastupdatedtime
  2273. --
  2274. -- Description: This procedure retrieves the last updated time from the 
  2275. --              subscriber database for a transactional/snapshot 
  2276. --              subscription.    
  2277. --
  2278. -- Parameters: @publisher sysname (mandatory)
  2279. --             @publisher_db sysname (mandatory)
  2280. --             @publication sysname (mandatory)
  2281. --             @subscription_type int (mandatory)
  2282. -- Notes: This procedure should always be called internally by 
  2283. --        sp_MSgetlastupdatedtime
  2284. --
  2285. -- Result: 'last updated time' nvarchar
  2286. --
  2287. -- Returns 0 - succeeded
  2288. --         1 - failed
  2289. --
  2290. -- Security: Sysadmin access only 
  2291. --
  2292. print 'Creating procedure sp_MSgettranlastupdatedtime'
  2293. print ''
  2294. go
  2295. create procedure sp_MSgettranlastupdatedtime(
  2296.     @publisher sysname,
  2297.     @publisher_db sysname,
  2298.     @publication sysname,
  2299.     @subscription_type int
  2300.     )
  2301. as
  2302. begin
  2303.     set nocount on
  2304.     declare @last_updated_time nvarchar(40)
  2305.     
  2306.     select @last_updated_time = null
  2307.  
  2308.     if object_id('MSreplication_subscriptions') is null
  2309.     begin
  2310.         select 'last updated time' = @last_updated_time
  2311.         raiserror(21384, 16, -1)        
  2312.         return 1
  2313.     end
  2314.     
  2315.     -- For subscriptions sharing an agent, 
  2316.     -- the control may not be passing in the publication
  2317.     -- name. 
  2318.     select @last_updated_time = convert(nvarchar(12), time, 112) +
  2319.                                 substring(convert(nvarchar(24), time, 121), 11,13)
  2320.       from MSreplication_subscriptions    
  2321.      where upper(@publisher) = upper(publisher)
  2322.        and @publisher_db = publisher_db
  2323.        and (((@publication is null or @publication = N'') and independent_agent = 0)
  2324.             or (@publication = publication))
  2325.        and @subscription_type = subscription_type
  2326.  
  2327.     select 'last updated time' = @last_updated_time
  2328.  
  2329.     if @last_updated_time is null
  2330.     begin
  2331.         raiserror(21384, 16, -1)
  2332.         return 1
  2333.     end
  2334.     return 0
  2335. end
  2336. go
  2337. exec sp_MS_marksystemobject 'sp_MSgettranlastupdatedtime'
  2338.  
  2339. -- 
  2340. -- Name: sp_MSgetmergelastupdatedtime
  2341. -- 
  2342. -- Description: This procedure retrieves the last updated time from the
  2343. --              subscriber database for a merge subscription.
  2344. --
  2345. -- Parameters: @publisher sysname (mandatory)
  2346. --             @publisher_db sysname (mandatory)
  2347. --             @publication sysname (mandatory)
  2348. --             @subscription_type int (mandatory)
  2349. -- Notes: This procedure should always be called internally by 
  2350. --        sp_MSgetlastupdatedtime
  2351. --
  2352. -- Result: 'last updated time' nvarchar
  2353. --
  2354. -- Returns: 0 - succeeded
  2355. --          1 - failed
  2356. --
  2357. -- Security: Sysadmin access only
  2358. --
  2359. print 'Creating procedure sp_MSgetmergelastupdatedtime'
  2360. print ''
  2361. go
  2362. create procedure sp_MSgetmergelastupdatedtime(
  2363.     @publisher sysname,
  2364.     @publisher_db sysname,
  2365.     @publication sysname,
  2366.     @subscription_type int
  2367.     )
  2368. as
  2369. begin
  2370.     set nocount on
  2371.     declare @last_updated_time nvarchar(40)
  2372.     declare @last_updated_datetime datetime
  2373.  
  2374.     select @last_updated_datetime = null
  2375.     select @last_updated_time = null
  2376.     
  2377.     if object_id('sysmergesubscriptions') is null or
  2378.        object_id('sysmergepublications') is null
  2379.     begin
  2380.         select 'last updated time' = @last_updated_time
  2381.         raiserror(21384, 16, -1)        
  2382.         return 1
  2383.     end
  2384.  
  2385.     select @last_updated_datetime = last_sync_date 
  2386.       from sysmergesubscriptions sms
  2387.     inner join sysmergepublications smp
  2388.         on sms.pubid = smp.pubid     
  2389.      where upper(@@servername) = upper(sms.subscriber_server)
  2390.        and sms.db_name =  db_name()
  2391.        and sms.subscription_type = @subscription_type
  2392.        and upper(smp.publisher) = upper(publisher)
  2393.        and smp.publisher_db = @publisher_db
  2394.        and smp.name = @publication
  2395.  
  2396.     if @last_updated_datetime is not null
  2397.     begin
  2398.         select @last_updated_time = convert(nvarchar(12), @last_updated_datetime, 112) +
  2399.                   substring(convert(nvarchar(24), @last_updated_datetime, 121), 11,13)
  2400.     end
  2401.  
  2402.     select 'last updated time' = @last_updated_time
  2403.  
  2404.     if @last_updated_time is null
  2405.     begin
  2406.         raiserror(21384, 16, -1)
  2407.         return 1
  2408.     end
  2409.     return 0
  2410. end
  2411. go
  2412. exec sp_MS_marksystemobject 'sp_MSgetmergelastupdatedtime'
  2413.  
  2414. --
  2415. -- Name: sp_MSgetlastupdatedtime
  2416. -- 
  2417. -- Description: This procedure is used internally by the ActiveX controls
  2418. --              to retrieve the last updated time of the specified 
  2419. --              subscription. 
  2420. --  
  2421. -- Parameters: @publisher sysname (mandatory)
  2422. --             @publisher_db sysname (mandatory)
  2423. --             @publication sysname (mandatory)
  2424. --             @subscription_type int (mandatory)
  2425. --             @publication_type int (mandatory) (1 - transactional/snapshot
  2426. --                                                2 - merge)
  2427. -- Returns: 0 - succeeded
  2428. --          1 - failed
  2429. --
  2430. -- Result: 'last updated time' nvarchar 
  2431. --
  2432. -- Security: Execute permission of this stored procedure is granted to public
  2433. --           but security check is performed inside the procedure to make
  2434. --           sure that only dbo of the subscriber database and server admin
  2435. --           can retrieve the last updated time successfully. 
  2436. --
  2437. print 'Creating procedure sp_MSgetlastupdatedtime'
  2438. print ''
  2439. go
  2440. create procedure sp_MSgetlastupdatedtime(
  2441.     @publisher sysname,
  2442.     @publisher_db sysname,
  2443.     @publication sysname,
  2444.     @subscription_type int,
  2445.     @publication_type int  -- 1 - transactional/snapshot, 2 - merge
  2446.     )
  2447. as
  2448. begin
  2449.     set nocount on
  2450.     declare @retcode int
  2451.     select @retcode = 0
  2452.  
  2453.     -- Security check
  2454.     exec @retcode = sp_MSreplcheck_subscribe    
  2455.     if @retcode<>0 or @@error<>0
  2456.         return 1
  2457.  
  2458.     if @publication_type in (0,1)
  2459.     begin
  2460.         exec @retcode = sp_MSgettranlastupdatedtime @publisher,
  2461.                                                     @publisher_db,
  2462.                                                     @publication,
  2463.                                                     @subscription_type
  2464.     end
  2465.     else
  2466.     begin
  2467.         exec @retcode = sp_MSgetmergelastupdatedtime @publisher,
  2468.                                                      @publisher_db,
  2469.                                                      @publication,
  2470.                                                      @subscription_type
  2471.     end
  2472.     return @retcode
  2473. end
  2474. go
  2475. exec sp_MS_marksystemobject 'sp_MSgetlastupdatedtime'
  2476.  
  2477. --
  2478. -- Name: fn_repladjustcolumnmap
  2479. --
  2480. -- Description: This function adjusts the bitmap for subscriber/destination tables
  2481. -- that have been altered and the relative column order do not match the actual
  2482. -- column id. The column_updated() bitmap for such tables need to be adjusted to
  2483. -- reflect relative column order before sending them to publisher 
  2484. --
  2485. -- Parameters: 
  2486. --    @objid    int - destination table object id
  2487. --     ,@total_col int - total number of columns in the table
  2488. --     ,@inmap varbinary(4000) input bitmap that is based on actual column id
  2489. --
  2490. -- Returns: varbinary(4000) output column that is based on relative column order
  2491. --
  2492. -- Security: Execute permission of this function is granted to public
  2493. -- 
  2494. raiserror('Creating function fn_repladjustcolumnmap', 0,1)
  2495. go
  2496. create function system_function_schema.fn_repladjustcolumnmap
  2497. (
  2498.     @objid    int
  2499.     ,@total_col int
  2500.     ,@inmap varbinary(4000)
  2501. returns varbinary(4000)
  2502. as
  2503. begin
  2504.     declare @colmap table (relativeorder int identity(1,1), colid int)
  2505.     declare
  2506.         @outmap varbinary(4000)
  2507.         ,@relpos int
  2508.         ,@colid int
  2509.         ,@bytepos int
  2510.         ,@bitpos int
  2511.         ,@num_bytes int
  2512.  
  2513.     --
  2514.     -- initialize
  2515.     --
  2516.     select @outmap = 0
  2517.     insert into @colmap (colid)
  2518.         select colid from syscolumns where id = @objid order by colid
  2519.     if (@@error != 0)
  2520.     begin
  2521.         return cast(NULL as varbinary(4000))
  2522.     end
  2523.  
  2524.     --
  2525.     -- for each column in the column map
  2526.     --
  2527.     declare #colmap_cursor cursor local fast_forward for 
  2528.         select relativeorder, colid from @colmap 
  2529.         order by relativeorder
  2530.     for read only
  2531.  
  2532.     open #colmap_cursor
  2533.     fetch #colmap_cursor into @relpos, @colid
  2534.     while (@@fetch_status = 0)
  2535.     begin
  2536.         --
  2537.         -- select the absolute column position
  2538.         --
  2539.         select @bytepos = 1 + ((@colid-1) / 8)
  2540.             ,@bitpos =  power(2, (@colid-1) % 8 ) 
  2541.  
  2542.         if (substring(@inmap, @bytepos, 1) & @bitpos = @bitpos)
  2543.         begin
  2544.             --
  2545.             -- set the relative position for this column in the output
  2546.             --
  2547.             select @bytepos = 1 + ((@relpos-1) / 8)
  2548.                 ,@bitpos =  power(2, (@relpos-1) % 8 )
  2549.                 ,@num_bytes = @total_col / 8 + 1
  2550.  
  2551.             select @outmap = substring(@outmap, 1, (@bytepos - 1)) + 
  2552.                 (convert(binary(1), substring(@outmap, @bytepos, 1) | convert(tinyint,@bitpos))) + 
  2553.                 substring(@outmap, (@bytepos + 1), (@num_bytes - @bytepos))
  2554.         end
  2555.  
  2556.         -- fetch next column mapping
  2557.         fetch #colmap_cursor into @relpos, @colid        
  2558.     end
  2559.     close #colmap_cursor
  2560.     deallocate #colmap_cursor
  2561.  
  2562.     return @outmap
  2563. end
  2564. go
  2565. grant execute on system_function_schema.fn_repladjustcolumnmap to public
  2566.  
  2567. --
  2568. -- Name: fn_replquotename
  2569. --
  2570. -- Description: This is simply a more complete implementation of quote_name()
  2571. --              that can handle longer strings. Note that this function is
  2572. --              hard-coded to do square-bracket quoting only.
  2573. --
  2574. -- Parameter: @string nvarchar(1998)
  2575. --
  2576. -- Returns: nvarchar(4000)
  2577. --
  2578. -- Security: Execute permission of this function is granted to public
  2579. -- 
  2580. print 'Creating function fn_replquotename'
  2581. print ''
  2582. go
  2583. create function system_function_schema.fn_replquotename(
  2584.     @string nvarchar(1998)
  2585.     ) returns nvarchar(4000)
  2586. begin
  2587.  
  2588.     declare @resulting_string nvarchar(4000)
  2589.     declare @string_len int 
  2590.     declare @char nchar(1)
  2591.     declare @index int    
  2592.  
  2593.     select @resulting_string = null
  2594.     if @string is not null
  2595.     begin
  2596.         select @string_len = len(@string)
  2597.         select @index = 1
  2598.  
  2599.         select @resulting_string = N'['
  2600.  
  2601.         while @index <=  @string_len
  2602.         begin
  2603.             select @char = substring(@string, @index, 1)
  2604.  
  2605.             select @resulting_string = @resulting_string + @char
  2606.             if @char = N']'
  2607.             begin
  2608.                 select @resulting_string = @resulting_string + N']'
  2609.             end
  2610.  
  2611.             select @index = @index + 1
  2612.         end
  2613.         select @resulting_string = @resulting_string + N']'
  2614.     end
  2615.     return @resulting_string
  2616. end
  2617. go
  2618.  
  2619. -- 
  2620. -- Name: fn_chariswhitespace
  2621. -- 
  2622. -- Description: This is a very simple function that checks whether a given
  2623. --              character is a white-space.
  2624. -- 
  2625. -- Parameters: @char nchar(1)
  2626. -- 
  2627. -- Notes:
  2628. -- 
  2629. -- Returns: bit
  2630. --          0 - The given character is not a white-space
  2631. --          1 - The given character is a white-space
  2632. -- 
  2633. -- Security: Execute permission of this function is granted to public
  2634. -- 
  2635. print 'Creating function fn_chariswhitespace'
  2636. print ''
  2637. go
  2638. create function system_function_schema.fn_chariswhitespace(
  2639.     @char nchar(1)
  2640.     ) returns bit
  2641. begin
  2642.     declare @result bit
  2643.  
  2644.     if @char in (N' ', nchar(9), nchar(10), nchar(13), N'')
  2645.     begin
  2646.         select @result = 1
  2647.     end
  2648.     else
  2649.     begin
  2650.         select @result = 0
  2651.     end
  2652.     return @result        
  2653. end
  2654. go
  2655.  
  2656. --
  2657. -- Name: fn_generateparameterpattern
  2658. --
  2659. -- Description: Given the name of a parameter (excluding the leading / or -), 
  2660. --              this function will return the pattern for matching the
  2661. --              parameter in a case-insensitive manner. For example
  2662. --  
  2663. --              select fn_generateparameterpattern(N'Ouptut')
  2664. -- 
  2665. --              will return
  2666. --
  2667. --              %[-/][Oo][Uu][Tt][Pp][Uu][Tt]%
  2668. --
  2669. -- Parameters: @parameter nvarchar(200)
  2670. --             
  2671. -- Notes: The leading / or - should be omitted from @parameter
  2672. --
  2673. -- Returns: nvarchar(806)
  2674. --
  2675. -- Security: Execute permission of this function is granted to public 
  2676. --
  2677. print 'Creating function fn_generateparameterpattern'
  2678. print ''
  2679. go
  2680. create function system_function_schema.fn_generateparameterpattern(
  2681.     @parameter nvarchar(200)
  2682.     ) returns nvarchar(806)
  2683. begin
  2684.     declare @pattern          nvarchar(806)
  2685.     declare @parameter_length int
  2686.     declare @i                int
  2687.     declare @c                nvarchar(1)
  2688.  
  2689.     select @pattern = N'%[-/]'
  2690.     select @i = 1
  2691.     select @parameter_length = len(@parameter)
  2692.     
  2693.     while @i <= @parameter_length
  2694.     begin
  2695.     select @c = substring(@parameter, @i, 1)        
  2696.     select @pattern = @pattern + N'[' + upper(@c collate SQL_Latin1_General_CP1_CS_AS) + lower(@c collate SQL_Latin1_General_CP1_CS_AS) + N']'
  2697.         select @i = @i + 1
  2698.     end 
  2699.     select @pattern = @pattern + '%'
  2700.     return @pattern
  2701. end
  2702. go
  2703.  
  2704. --
  2705. -- Name: fn_skipparameterargument
  2706. --
  2707. -- Description: This function basically removes the first non-parameter
  2708. --              token from the given command. It is designed to handle
  2709. --              square-bracket quoted or double-quoted parameter arguments.
  2710. --              Note that all white-spaces trailing the removed argument will 
  2711. --              also be removed in the returned command.
  2712. --
  2713. -- Parameters: @command nvarchar(3200)
  2714. -- 
  2715. -- Returns: nvarchar(3200)
  2716. --
  2717. -- Security: Execute permission of this function is granted to public
  2718. --              
  2719. print 'Creating function fn_skipparameterargument'
  2720. print ''
  2721. go
  2722. create function system_function_schema.fn_skipparameterargument(
  2723.     @command nvarchar(3200)
  2724.     ) returns nvarchar(3200)
  2725. begin
  2726.     declare @state int
  2727.     declare @i int
  2728.     declare @char nvarchar(1)
  2729.     declare @command_length int
  2730.     declare @state_start int
  2731.     declare @state_in_dquote_argument int
  2732.     declare @state_seen_matching_dquote int
  2733.     declare @state_in_square_bracket_argument int
  2734.     declare @state_seen_matching_bracket int
  2735.     declare @state_reached_end_of_argument int
  2736.     declare @state_in_unquoted_argument int
  2737.     declare @state_exit int
  2738.     -- Initializations
  2739.     select @state_start = 0
  2740.     select @state_in_dquote_argument = 1    
  2741.     select @state_seen_matching_dquote = 2
  2742.     select @state_in_square_bracket_argument = 3
  2743.     select @state_seen_matching_bracket = 4
  2744.     select @state_reached_end_of_argument = 5
  2745.     select @state_in_unquoted_argument = 6
  2746.     select @state_exit = 7
  2747.  
  2748.     select @i = 1
  2749.     select @state = @state_start
  2750.     select @command_length = len(@command)  
  2751.  
  2752.     while @i <= @command_length
  2753.     begin
  2754.  
  2755.         select @char = substring(@command,@i,1)
  2756.         select @state = 
  2757.             case @state 
  2758.             when @state_start then
  2759.                 case 
  2760.                 when fn_chariswhitespace(@char) = 1 then @state_start   
  2761.                 when @char in (N'-',N'/') then @state_exit
  2762.                 when @char in (N'[') then @state_in_square_bracket_argument
  2763.                 when @char in (N'"') then @state_in_dquote_argument
  2764.                 else @state_in_unquoted_argument
  2765.                 end
  2766.             when @state_in_dquote_argument then
  2767.                 case 
  2768.                 when @char in (N'"') then @state_seen_matching_dquote
  2769.                 else @state_in_dquote_argument
  2770.                 end
  2771.             when @state_seen_matching_dquote then
  2772.                 case 
  2773.                 when @char in (N'"') then @state_in_dquote_argument 
  2774.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  2775.                 else @state_exit
  2776.                 end
  2777.             when @state_in_square_bracket_argument then
  2778.                 case
  2779.                 when @char in (N']') then @state_seen_matching_bracket
  2780.                 else @state_in_square_bracket_argument  
  2781.                 end
  2782.             when @state_seen_matching_bracket then
  2783.                 case 
  2784.                 when @char in (N']') then @state_in_square_bracket_argument
  2785.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  2786.                 else @state_exit
  2787.                 end
  2788.             when @state_reached_end_of_argument then
  2789.                 case 
  2790.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  2791.                 else @state_exit    
  2792.                 end
  2793.             when @state_in_unquoted_argument then
  2794.                 case
  2795.                 when fn_chariswhitespace(@char) = 1 then @state_reached_end_of_argument
  2796.                 else @state_in_unquoted_argument
  2797.                 end
  2798.             else @state         
  2799.             end 
  2800.  
  2801.         if @state = @state_exit
  2802.         begin
  2803.             goto done
  2804.         end
  2805.     select @i = @i + 1
  2806.     end -- while
  2807. done:
  2808.     select @command = substring(@command, @i, @command_length - @i + 1)
  2809.     return @command 
  2810. end
  2811. go  
  2812.  
  2813. -- 
  2814. -- Name: fn_removeparameterwithargument
  2815. -- 
  2816. -- Description: This function removes all instances of a parameter and their
  2817. --              arguments from a given command line.
  2818. --
  2819. -- Notes: @parameter must be specified without the leading / or -
  2820. --
  2821. -- Parameters: @command nvarchar(3200)
  2822. --             @parameter nvarchar(200)
  2823. --
  2824. -- Returns: @nvarchar(3200)
  2825. -- 
  2826. -- Security: Execute permission of this function is granted to public
  2827. --
  2828. print 'Creating function fn_reomveparameterwithargument'
  2829. print ''
  2830. go
  2831. create function system_function_schema.fn_removeparameterwithargument(
  2832.     @command nvarchar(3200),
  2833.     @parameter nvarchar(200)
  2834.     ) returns nvarchar(3200)
  2835. begin
  2836.  
  2837.     declare @pattern nvarchar(806)
  2838.     declare @resulting_command nvarchar(3200)
  2839.     declare @command_length int
  2840.     declare @pattern_start int
  2841.     declare @first_iteration bit
  2842.     declare @parameter_length int
  2843.  
  2844.     select @first_iteration = 1
  2845.     select @pattern = fn_generateparameterpattern(@parameter)
  2846.     select @parameter_length = len(@parameter) + 1 -- leading - or /
  2847.     
  2848.     select @resulting_command = N''
  2849.     select @pattern_start = patindex(@pattern,@command) 
  2850.     while @pattern_start <> 0 and @pattern_start is not NULL
  2851.     begin
  2852.         select @command_length = len(@command)
  2853.  
  2854.         -- Check if the pattern found is properly delimited in the command.
  2855.         -- If so, try to skip over the next token. 
  2856.         if (@pattern_start = 1 and @first_iteration = 1 or
  2857.             (@pattern_start > 1 and fn_chariswhitespace(substring(@command, @pattern_start - 1, 1)) = 1))  and
  2858.             (fn_chariswhitespace(substring(@command, @pattern_start + @parameter_length, 1)) = 1)             
  2859.         begin
  2860.             -- Add everything before the parameter to the resulting command
  2861.             select @resulting_command = @resulting_command + rtrim(substring(@command, 1, @pattern_start - 1))
  2862.  
  2863.             -- Eat the parameter
  2864.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  2865.  
  2866.             -- Skip over the argument of the parameter
  2867.             select @command = fn_skipparameterargument(@command)
  2868.  
  2869.             if @resulting_command <> N''
  2870.             begin
  2871.                 select @resulting_command = @resulting_command + N' '
  2872.             end
  2873.         end  
  2874.         else    
  2875.         begin
  2876.             -- Not a properly delimited parameter so transfer the 
  2877.             -- matching substring to the resulting command and
  2878.             -- eat the substring in the process
  2879.             select @resulting_command = @resulting_command + substring(@command, 1, @pattern_start + @parameter_length - 1)
  2880.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  2881.         end
  2882.         select @first_iteration = 0
  2883.         select @pattern_start = patindex(@pattern, @command) 
  2884.     end 
  2885.     select @resulting_command = @resulting_command + @command
  2886.     return @resulting_command
  2887. end
  2888. go
  2889.  
  2890. --
  2891. -- Name: fn_updateparameterwithargument
  2892. --
  2893. -- Description: This function updates the argument value of the specified
  2894. --              parameter in the given command line. If there are multiple
  2895. --              instances of the specified parameter in the command line, 
  2896. --              only the first instance will be updated and all subsequent 
  2897. --              instances will be removed. If the command line does not 
  2898. --              contain the specified parameter in the first place, this
  2899. --              function will append the specified parameter and argument 
  2900. --              to the command line.
  2901. --
  2902. -- Notes: Any quoting that is required for the argument should be done
  2903. --        before calling this function.
  2904. --
  2905. -- Parameters: @command nvarchar(3200)
  2906. --             @parameter nvarchar(200)
  2907. --             @argument nvarchar(1000)
  2908. --            
  2909. -- Returns: nvarchar(3200)
  2910. --
  2911. -- Security: Execute permission of this function is granted to public
  2912. --
  2913. print 'Creating function fn_updateparameterwithargument'
  2914. print ''
  2915. go
  2916. create function system_function_schema.fn_updateparameterwithargument(
  2917.     @command nvarchar(3200),
  2918.     @parameter nvarchar(200),
  2919.     @argument  nvarchar(1000)
  2920.     ) returns nvarchar(3200)
  2921. begin
  2922.     declare @pattern nvarchar(806)
  2923.     declare @resulting_command nvarchar(3200)
  2924.     declare @command_length int
  2925.     declare @pattern_start int
  2926.     declare @first_iteration bit
  2927.     declare @parameter_length int
  2928.     declare @found_parameter bit
  2929.     
  2930.     select @first_iteration = 1
  2931.     select @found_parameter = 0
  2932.     select @pattern = fn_generateparameterpattern(@parameter)
  2933.     select @parameter_length = len(@parameter) + 1 -- leading - or /
  2934.  
  2935.     select @resulting_command = N''
  2936.     select @pattern_start = patindex(@pattern,@command)
  2937.         
  2938.     if @argument is null
  2939.     begin
  2940.         select @argument = N''
  2941.     end
  2942.  
  2943.     while @pattern_start <> 0 and @pattern_start is not null
  2944.     begin
  2945.         select @command_length = len(@command)
  2946.  
  2947.         -- Check if the pattern found is properly delimited in the command,
  2948.         -- If so, try to change the argument of the parameter with the given
  2949.         -- value.
  2950.         if (@pattern_start = 1 and @first_iteration = 1 or
  2951.             (@pattern_start > 1 and fn_chariswhitespace(substring(@command, @pattern_start - 1, 1)) = 1)) and
  2952.             (fn_chariswhitespace(substring(@command, @pattern_start + @parameter_length, 1)) = 1)
  2953.         begin
  2954.  
  2955.             -- Add everything before the parameter to the resulting command
  2956.             select @resulting_command = @resulting_command + rtrim(substring(@command, 1, @pattern_start - 1))
  2957.  
  2958.             -- Add back the parameter with the specified argument
  2959.             if @resulting_command <> ''
  2960.             begin
  2961.                 select @resulting_command = @resulting_command + N' '
  2962.             end
  2963.             select @resulting_command = @resulting_command + N'-' + @parameter + N' ' + rtrim(ltrim(@argument)) + ' '
  2964.  
  2965.             -- Remove the leading part of the command up to the begining of the
  2966.             -- matching pattern
  2967.             select @command = substring(@command, @pattern_start, @command_length - @pattern_start + 1)
  2968.  
  2969.             -- Remove all traces of the specified parameter from the remaining
  2970.             -- command line
  2971.             select @command = fn_removeparameterwithargument(@command, @parameter)
  2972.             select @found_parameter = 1
  2973.         end
  2974.         else
  2975.         begin
  2976.             -- Not a properly delimited parameter so transfer the 
  2977.             -- matching substring to the resulting command and
  2978.             -- eat the substring in the process
  2979.             select @resulting_command = @resulting_command + substring(@command, 1, @pattern_start + @parameter_length - 1)
  2980.             select @command = substring(@command, @pattern_start + @parameter_length, @command_length - @pattern_start - @parameter_length + 1)
  2981.         end
  2982.  
  2983.         select @first_iteration = 0
  2984.         select @pattern_start = patindex(@pattern, @command)
  2985.     end
  2986.  
  2987.     select @resulting_command = @resulting_command + @command
  2988.  
  2989.     if @found_parameter = 0
  2990.     begin
  2991.         select @resulting_command = rtrim(@resulting_command) + N' ' + N'-' +
  2992.                @parameter + N' ' + rtrim(ltrim(@argument)) 
  2993.     end
  2994.     return @resulting_command
  2995. end
  2996. go
  2997.  
  2998. --
  2999. -- Name: sp_MSreplcheckoffloadserver
  3000. --
  3001. -- Description: A simple procedure for checking whether a specified
  3002. --              offload server name contains invalid characters.
  3003. --
  3004. -- Parameter: @offloadserver sysname (mandatory)
  3005. --
  3006. -- Security: Admin only
  3007. --
  3008. -- Returns: 0 - The specified offload server name doesn't contain invalid 
  3009. --             characters
  3010. --         1 - The specified offload server name contains invalid characters
  3011. --
  3012. print ''
  3013. print 'Creating procedure sp_MSreplcheckoffloadserver'
  3014. go
  3015. create procedure sp_MSreplcheckoffloadserver (
  3016.     @offloadserver sysname
  3017.     )
  3018. as 
  3019. begin
  3020.     -- @offload_server being null is ok
  3021.     -- look for '\'
  3022.     if 0 < charindex('\', @offloadserver)
  3023.     begin
  3024.         raiserror(21368,-1,-1,N'\')
  3025.         return 1
  3026.     end
  3027.     return 0
  3028. end
  3029. go
  3030. exec sp_MS_marksystemobject sp_MSreplcheckoffloadserver
  3031. go
  3032.  
  3033. --
  3034. -- Name: fn_MSrepl_get_unique_name
  3035. --
  3036. -- Description: Use the prefixes passed in to generate a unique name based on a new GUID
  3037. -- which is less than 100 characters (100 is task name limit) as
  3038. -- 'prefix1-prefix2-prefix3-prefix4-hex_of_guid'
  3039. -- All prefixes are optional.
  3040. --
  3041. -- Security: To public
  3042. --
  3043. raiserror('Creating function fn_repluniquename', 0,1)
  3044. go
  3045.  
  3046. create function system_function_schema.fn_repluniquename (
  3047. -- cannot use newid() in a UDF
  3048.     @guid uniqueidentifier,
  3049.     @prefix1 sysname = NULL,
  3050.     @prefix2 sysname = NULL,
  3051.     @prefix3 sysname = NULL,
  3052.     @prefix4 sysname = NULL
  3053.     ) returns nvarchar(100)
  3054. as
  3055. begin
  3056.     declare @name nvarchar(100)
  3057.     select @name = N''
  3058.  
  3059.     -- Max len is (16 + 1) * 4 + 32 = 100
  3060.     if @prefix1 is not null
  3061.         select @name = @name + CONVERT(nvarchar(16),@prefix1) + N'-'
  3062.     if @prefix2 is not null
  3063.         select @name = @name + CONVERT(nvarchar(16),@prefix2) + N'-'
  3064.     if @prefix3 is not null
  3065.         select @name = @name + CONVERT(nvarchar(16),@prefix3) + N'-'
  3066.     if @prefix4 is not null
  3067.         select @name = @name + CONVERT(nvarchar(16),@prefix4) + N'-'
  3068.  
  3069.     select @name = @name + replace(convert(nvarchar(36), @guid), N'-',N'')
  3070.     return @name
  3071. end
  3072. go
  3073.  
  3074. print ''
  3075. print 'Creating procedure sp_MSget_file_existence'
  3076. go
  3077. create procedure sp_MSget_file_existence (
  3078. @filename nvarchar(260),
  3079. @exists bit = 0 output
  3080. )
  3081. AS
  3082.     SET NOCOUNT ON
  3083.  
  3084.     DECLARE @command nvarchar(512)
  3085.     DECLARE @retcode int
  3086.     declare @echo_text nvarchar(20)
  3087.  
  3088.     select @echo_text = 'file_exists'
  3089.  
  3090.     /*
  3091.     ** The return code from xp_cmdshell is not a reliable way to check whether the file exists or
  3092.     ** not. It is always 0 on Win95 as long as xp_cmdshell succeeds.
  3093.     */  
  3094.  
  3095.     select @command = N'if exist "' + @filename + N'" echo ' + @echo_text
  3096.  
  3097.     create table #text_ret(cmdoutput nvarchar(20) collate database_default null)
  3098.  
  3099.     insert into #text_ret exec @retcode = master..xp_cmdshell @command
  3100.     if @@error <> 0 or @retcode <> 0
  3101.         return 1
  3102.  
  3103.     if exists (select * from #text_ret where ltrim(rtrim(cmdoutput)) = @echo_text)
  3104.         select @exists = 1
  3105.     else 
  3106.         select @exists = 0
  3107.  
  3108.     drop table #text_ret
  3109. go
  3110. EXEC dbo.sp_MS_marksystemobject sp_MSget_file_existence
  3111. GO
  3112.  
  3113.  
  3114. raiserror('Creating procedure sp_MSrepl_isdbowner', 0,1)
  3115. go
  3116. CREATE PROCEDURE sp_MSrepl_isdbowner 
  3117.     @dbname nvarchar(255)
  3118. AS
  3119. BEGIN
  3120.     SET NOCOUNT ON
  3121.     DECLARE @retcode int
  3122.     DECLARE @cmd      nvarchar(255)
  3123.     DECLARE @isdbowner int
  3124.  
  3125.     SELECT @retcode = has_dbaccess(@dbname)
  3126.     IF (@retcode IS NULL) OR (@retcode = 0)
  3127.     BEGIN
  3128.         /* 
  3129.         ** Either no access or database not found 
  3130.         ** No need to go further
  3131.         */
  3132.         RETURN 0
  3133.     END
  3134.  
  3135.     SELECT @cmd = 'USE ' + quotename(@dbname) + ' SELECT @isdbowner = is_member(''db_owner'')'
  3136.     EXEC sp_executesql @cmd, N'@isdbowner int output', @isdbowner output
  3137.  
  3138.     RETURN isnull(@isdbowner, 0)
  3139. END
  3140. GO
  3141.  
  3142. raiserror('Creating procedure sp_resyncmergesubscription', 0,1)
  3143. go
  3144. CREATE PROCEDURE sp_resyncmergesubscription 
  3145.     @publisher            sysname = NULL,
  3146.     @publisher_db        sysname = NULL,
  3147.     @publication        sysname,
  3148.     @subscriber            sysname = NULL,
  3149.     @subscriber_db        sysname = NULL,
  3150.     @resync_type        int, --0:force convergence, 1: since last successful validation, 2:since a given date
  3151.     @resync_date_str    nvarchar(30) = NULL
  3152. AS
  3153.     declare @retcode             int
  3154.     declare @subid                uniqueidentifier
  3155.     declare @pubid                uniqueidentifier
  3156.     declare @subscriber_srvid     int
  3157.     declare @resync_gen            int
  3158.     declare @resync_date        datetime
  3159.     /*
  3160.     ** Security Check
  3161.     */
  3162.  
  3163.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  3164.     IF @@ERROR <> 0 or @retcode <> 0
  3165.         return (1)
  3166.  
  3167.     if isdate(@resync_date_str)=0 and @resync_type=2
  3168.     begin
  3169.         raiserror(21370, 16, -1, @resync_date_str)
  3170.         return (1)
  3171.     end
  3172.     if @resync_date_str is not NULL
  3173.         select @resync_date=convert(datetime, @resync_date_str)
  3174.     else
  3175.         select @resync_date = NULl
  3176.     
  3177.     /*
  3178.     ** parameter checking for null/not-null; including validity of @resync_type and @resync_date
  3179.     */
  3180.  
  3181.     if ((@publisher is NULL and @subscriber is NULL) or
  3182.        (@publisher is not NULL and @subscriber is not NULL) or
  3183.        (@publisher is NULL and @publisher_db is not NULL) or
  3184.        (@subscriber is NULL and @subscriber_db is not NULL) or
  3185.        (@publisher is not NULL and @publisher_db is NULL) or
  3186.        (@subscriber is not NULL and @subscriber_db is NULL))
  3187.        begin
  3188.                raiserror(21294, 16, -1)
  3189.                return (1)
  3190.        end
  3191.  
  3192.     if @resync_type<0 or @resync_type>2
  3193.         begin
  3194.             raiserror(21296, 16, -1)
  3195.             return (1)
  3196.         end
  3197.  
  3198.     if @publisher is NULL    
  3199.         select @publisher=@@SERVERNAME
  3200.     if @publisher_db is NULL
  3201.         select @publisher_db=db_name()
  3202.     if @subscriber is NULL
  3203.         select @subscriber=@@SERVERNAME
  3204.     if @subscriber_db is NULL
  3205.         select @subscriber_db=db_name()
  3206.         
  3207.     select @pubid = pubid from sysmergepublications where name=@publication and lower(publisher)=lower(@publisher) and publisher_db=@publisher_db
  3208.     if (@pubid is null)
  3209.         begin
  3210.             RAISERROR (20026, 16, -1, @publication)
  3211.             return (1)
  3212.         end
  3213.     select @subscriber_srvid=srvid from master..sysservers where LOWER(srvname)=LOWER(@subscriber) collate database_default
  3214.     select @subid=subid from sysmergesubscriptions where pubid=@pubid and srvid=@subscriber_srvid and db_name=@subscriber_db
  3215.     if @resync_type > 0 --since a given date or last validation    
  3216.         begin
  3217.             if @resync_type = 1    -- last validation time; make sure resync_date is not NULL in this case; 
  3218.                 begin
  3219.                     select @resync_date=last_validated from sysmergesubscriptions where subid=@subid
  3220.                     -- invalid case - there is no prior validation, this call is a non-op.
  3221.                     if @resync_date is NULL
  3222.                         begin
  3223.                             raiserror(21370, 16, -1)
  3224.                             return (1)
  3225.                         end
  3226.                 end
  3227.                 
  3228.             declare @guidnull uniqueidentifier
  3229.             set @guidnull= '00000000-0000-0000-0000-000000000000'
  3230.             
  3231.             exec sp_MSlocalizeinterruptedgenerations
  3232.             select @resync_gen=NULL
  3233.             select top 1 @resync_gen=generation from MSmerge_genhistory 
  3234.                 where     coldate > @resync_date 
  3235.                         and art_nick in (select nickname from sysmergearticles where pubid=@pubid)
  3236.                         and guidlocal <> @guidnull
  3237.                     order by coldate ASC
  3238.             -- this is valid case, meaning there is no need to do any resynchronization
  3239.             if @resync_gen is NULL
  3240.                 begin
  3241.                     return (0)
  3242.                 end
  3243.         end
  3244.     else if @resync_type=0
  3245.         select @resync_gen=0 -- force convergence case
  3246.     update  sysmergesubscriptions  set resync_gen=@resync_gen where subid=@subid
  3247.     if @@ERROR<>0
  3248.         begin
  3249.             raiserror(21298, 16, -1)
  3250.             return (1)
  3251.         end
  3252. Go
  3253. EXEC dbo.sp_MS_marksystemobject sp_resyncmergesubscription
  3254. GO
  3255. grant exec on sp_resyncmergesubscription to public
  3256. go
  3257.  
  3258.  
  3259.  
  3260. raiserror('Creating procedure sp_MSget_qualified_name', 0,1)
  3261. GO
  3262. CREATE PROCEDURE sp_MSget_qualified_name (
  3263.     @object_id                int,                         
  3264.     @qualified_name            nvarchar(512)    output       
  3265. )AS
  3266.     if object_name(@object_id) is not null
  3267.         select @qualified_name = quotename(user_name(OBJECTPROPERTY(@object_id,'OwnerId'))) collate database_default + 
  3268.             N'.' + quotename(object_name(@object_id)) collate database_default
  3269.     else
  3270.         select @qualified_name = NULL
  3271. GO
  3272. exec dbo.sp_MS_marksystemobject sp_MSget_qualified_name
  3273. go
  3274.  
  3275.  
  3276. raiserror('Creating procedure sp_MSdrop_object', 0,1)
  3277. GO
  3278.  
  3279. CREATE PROCEDURE sp_MSdrop_object (
  3280.         @object_id int = NULL,
  3281.         @object_name sysname = NULL,
  3282.         @object_owner sysname = NULL
  3283.         )
  3284.     AS
  3285.  
  3286.     SET NOCOUNT ON
  3287.  
  3288.     declare @cmd nvarchar(1000)
  3289.     
  3290.     if @object_name is not null
  3291.     begin
  3292.         declare @owner_id int
  3293.         if @object_owner is null
  3294.             select @owner_id = user_id()
  3295.         else
  3296.             select @owner_id = user_id(@object_owner)
  3297.         select @object_id = id from sysobjects where
  3298.             name = @object_name and
  3299.             uid = @owner_id
  3300.        end
  3301.  
  3302.        if @object_id is not null
  3303.        begin
  3304.            exec dbo.sp_MSget_qualified_name @object_id, @cmd output
  3305.            if objectproperty(@object_id, 'IsTable') = 1
  3306.                select @cmd = 'drop table ' + @cmd
  3307.            else if objectproperty(@object_id, 'IsProcedure') = 1
  3308.                select @cmd = 'drop procedure ' + @cmd
  3309.            else if objectproperty(@object_id, 'IsTrigger') = 1
  3310.                select @cmd = 'drop trigger ' + @cmd
  3311.            else if objectproperty(@object_id, 'IsView') = 1
  3312.                select @cmd = 'drop view ' + @cmd
  3313.        end
  3314.  
  3315.        exec (@cmd)
  3316.        if @@error <> 0
  3317.            return(1)
  3318.  
  3319. GO
  3320.  
  3321. print ''
  3322. print 'Creating procedure sp_isarticlecolbitset'
  3323. go
  3324.  
  3325. create procedure sp_isarticlecolbitset @colid int, @colbitmap binary(32)
  3326. as
  3327. declare @word tinyint
  3328. declare @mval int
  3329. declare @mask  smallint
  3330.  
  3331. select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  3332. select @mval = power(2, (@colid-1) % 16 )
  3333. select @mask = convert( smallint, convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  3334.  
  3335.  
  3336. if convert( binary(2), substring( convert( nchar(16),@colbitmap), @word, 1 ) ) & @mask = @mask 
  3337. begin   
  3338.    return 1
  3339. end
  3340. else
  3341. begin
  3342.    return 0
  3343. end
  3344.  
  3345. go
  3346.  
  3347. EXEC dbo.sp_MS_marksystemobject sp_isarticlecolbitset
  3348. GO
  3349. grant exec on sp_isarticlecolbitset to public
  3350. go
  3351.  
  3352. print ''
  3353. print 'Creating procedure sp_getarticlepkcolbitmap'
  3354. go
  3355.  
  3356. create procedure sp_getarticlepkcolbitmap @tabid int, @colbitmap binary(32) output
  3357. as
  3358. declare @pkindid int
  3359. declare @indkey int
  3360. declare @colid int
  3361. declare @word tinyint
  3362. declare @mval    int
  3363. declare @mask    binary(2)
  3364. declare @wordval binary(2)
  3365. declare @objname nvarchar(265)
  3366.  
  3367. select @colbitmap = 0x00
  3368.  
  3369. if exists( select * from sysobjects where id = @tabid and xtype = 'V' )
  3370. begin
  3371.     select @pkindid = 1
  3372. end
  3373. else
  3374. begin
  3375.     select @pkindid = indid from sysindexes where id = @tabid and status & 2048 <> 0
  3376. end
  3377.  
  3378. select @indkey = 1
  3379. select @objname = QUOTENAME(user_name(OBJECTPROPERTY(@tabid, 'OwnerId'))) collate database_default + N'.' collate database_default + QUOTENAME(object_name( @tabid )) collate database_default 
  3380.  
  3381. while @indkey <= 16 and index_col( @objname, @pkindid, @indkey ) is not null
  3382. begin
  3383.     select @colid = colid from syscolumns where id = @tabid 
  3384.            and name = index_col( @objname, @pkindid, @indkey )
  3385.     select @word = convert(tinyint, 16 - floor((@colid-1)/16))
  3386.  
  3387.     select @mval = power(2, (@colid-1) % 16 )
  3388.     select @mask = convert( binary(2), substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) )                                 
  3389.  
  3390.     select @wordval = convert( binary(2), substring( convert( nchar(16), @colbitmap ), @word, 1 ) )
  3391.     select @wordval = convert( binary(2), convert( smallint, @wordval) | convert( smallint, @mask) )
  3392.  
  3393.     select @colbitmap = convert(binary(32), STUFF( convert(nchar(16),@colbitmap), @word, 1, convert( nchar(1),@wordval))) 
  3394.       
  3395.     select @indkey = @indkey + 1
  3396. end
  3397. go
  3398.  
  3399. EXEC dbo.sp_MS_marksystemobject sp_getarticlepkcolbitmap
  3400. GO
  3401.  
  3402. grant exec on sp_getarticlepkcolbitmap to public
  3403. go
  3404.  
  3405.  
  3406. raiserror('Creating procedure sp_MSsubst_filter_name', 0,1)
  3407. GO
  3408. create procedure sp_MSsubst_filter_name 
  3409. @srch_string nvarchar(500), 
  3410. @rplc_string nvarchar(500), 
  3411. @filter_clause nvarchar(4000) output
  3412. as
  3413.  
  3414. declare @expansion int  -- BYTES data will be expanded/contracted by
  3415. declare @subst_offset int -- CHARACTER OFFSET at which to perform string operations
  3416.  
  3417. select @expansion = datalength(@rplc_string) - datalength(@srch_string) 
  3418. select @subst_offset = 0
  3419.  
  3420. -- Note!  procedure is case insensitive
  3421.  
  3422. select @subst_offset = charindex( upper(@srch_string), upper(@filter_clause), @subst_offset )
  3423. while( @subst_offset <> 0 )
  3424. begin
  3425.     if datalength( @filter_clause ) + @expansion > 8000
  3426.     begin
  3427.         -- buffer overflow, return error
  3428.         return 1
  3429.     end
  3430.     else
  3431.     begin
  3432.         select @filter_clause = stuff( @filter_clause, @subst_offset, datalength( @srch_string ) / 2, @rplc_string )
  3433.         select @subst_offset = @subst_offset + @expansion / 2
  3434.     end
  3435.     select @subst_offset = charindex( upper(@srch_string), upper(@filter_clause), @subst_offset )
  3436. end
  3437. return 0
  3438. go
  3439.  
  3440. raiserror('Creating procedure sp_MSsubst_filter_names', 0,1)
  3441. GO
  3442.  
  3443. create procedure sp_MSsubst_filter_names 
  3444. @owner sysname, 
  3445. @table sysname, 
  3446. @filter_clause nvarchar(4000) output
  3447. as
  3448. declare @retcode int
  3449. declare @rplc_string nvarchar( 513 )
  3450.  
  3451. if @filter_clause is null or @table is null
  3452. begin 
  3453.     -- error, @filter_clause cannot be null
  3454.     return 1
  3455. end
  3456.  
  3457. if @owner is not null
  3458. begin
  3459.     select @rplc_string = QUOTENAME(@owner) + N'.'
  3460. end
  3461. else
  3462. begin
  3463.     select @rplc_string = N''
  3464. end
  3465.  
  3466. select @rplc_string = @rplc_string + QUOTENAME(@table)
  3467.  
  3468. exec @retcode = sp_MSsubst_filter_name N'<<TABLE>>', @rplc_string, @filter_clause output 
  3469. if @retcode <> 0 or @@error <> 0
  3470. begin
  3471.     return 1
  3472. end
  3473.  
  3474. return 0
  3475.  
  3476. raiserror('Creating procedure sp_MSreplcheck_name', 0,1)
  3477. GO
  3478.  
  3479. CREATE PROCEDURE sp_MSreplcheck_name
  3480.     @name            sysname,
  3481.     @raise_error    bit = 1
  3482. AS
  3483.     declare @index    int
  3484.  
  3485.     Set nocount on
  3486.  
  3487.     -- Name cannot be NULL or empty ("")
  3488.     -- Blank identifiers (" ") are allowed
  3489.     IF (@name is null OR datalength(@name) = 0)
  3490.     begin
  3491.         if @raise_error = 1
  3492.             raiserror (15004,16,-1)
  3493.         return (1)
  3494.     end
  3495.  
  3496.     -- Check for proscribed characters
  3497.  
  3498.     declare @length int
  3499.     select @length = datalength( @name ) / 2
  3500.     select @index = 1
  3501.     while @index < @length
  3502.     begin
  3503.         if( 0 = unicode( substring( @name, @index, 1 ) ) )
  3504.         begin
  3505.             if @raise_error = 1
  3506.                 raiserror(15006,16,-1,@name)
  3507.             return (1)
  3508.         end
  3509.  
  3510.         select @index = @index + 1
  3511.     end
  3512.  
  3513.     --check for other proscribed characters
  3514.  
  3515.     select @index = charindex( N'%', @name)
  3516.     if (@index <> 0)
  3517.     begin
  3518.         if @raise_error = 1
  3519.             raiserror(15006,16,-1,@name)
  3520.         return (1)
  3521.     end
  3522.     select @index = charindex(N'*', @name)
  3523.     if (@index <> 0)
  3524.     begin
  3525.         if @raise_error = 1
  3526.             raiserror(15006,16,-1,@name)
  3527.         return (1)
  3528.     end
  3529.     select @index = charindex(N'[', @name)
  3530.     if (@index <> 0)
  3531.     begin
  3532.         if @raise_error = 1
  3533.             raiserror(15006,16,-1,@name)
  3534.         return (1)
  3535.     end
  3536.     select @index = charindex(N']', @name)
  3537.     if (@index <> 0)
  3538.     begin
  3539.         if @raise_error = 1
  3540.             raiserror(15006,16,-1,@name)
  3541.         return (1)
  3542.     end
  3543.     select @index = charindex(N'|', @name)
  3544.     if (@index <> 0)
  3545.     begin
  3546.         if @raise_error = 1
  3547.             raiserror(15006,16,-1,@name)
  3548.         return (1)
  3549.     end
  3550.     select @index = charindex(N':', @name)
  3551.     if (@index <> 0)
  3552.     begin
  3553.         if @raise_error = 1
  3554.             raiserror(15006,16,-1,@name)
  3555.         return (1)
  3556.     end
  3557.     select @index = charindex(N'"', @name)
  3558.     if (@index <> 0)
  3559.     begin
  3560.         if @raise_error = 1
  3561.             raiserror(15006,16,-1,@name)
  3562.         return (1)
  3563.     end
  3564.     select @index = charindex(N'?', @name)
  3565.     if (@index <> 0)
  3566.     begin
  3567.         if @raise_error = 1
  3568.             raiserror(15006,16,-1,@name)
  3569.         return (1)
  3570.     end
  3571.     /*
  3572.     ** Fix 52855 - allow single quote
  3573.     **
  3574.     select @index = charindex(N'''', @name)
  3575.     if (@index <> 0)
  3576.     begin
  3577.         if @raise_error = 1
  3578.             raiserror(15006,16,-1,@name)
  3579.         return (1)
  3580.     end
  3581.     */
  3582.     select @index = charindex(N'\', @name)
  3583.     if (@index <> 0)
  3584.     begin
  3585.         if @raise_error = 1
  3586.             raiserror(15006,16,-1,@name)
  3587.         return (1)
  3588.     end
  3589.     select @index = charindex(N'/', @name)
  3590.     if (@index <> 0)
  3591.     begin
  3592.         if @raise_error = 1
  3593.             raiserror(15006,16,-1,@name)
  3594.         return (1)
  3595.     end
  3596.     select @index = charindex(N'<', @name)
  3597.     if (@index <> 0)
  3598.     begin
  3599.         if @raise_error = 1
  3600.             raiserror(15006,16,-1,@name)
  3601.         return (1)
  3602.     end
  3603.     select @index = charindex(N'>', @name)
  3604.     if (@index <> 0)
  3605.     begin
  3606.         if @raise_error = 1
  3607.             raiserror(15006,16,-1,@name)
  3608.         return (1)
  3609.     end
  3610.     
  3611.     -- return success
  3612.  
  3613.     return (0) 
  3614. GO
  3615.     
  3616.  
  3617. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_name
  3618. go
  3619.  
  3620.  
  3621.  
  3622. raiserror('Creating procedure sp_MScheckvalidsystables', 0,1)
  3623. GO
  3624.  
  3625. create procedure sp_MScheckvalidsystables  @validsubs int output
  3626. AS
  3627.     if not exists (select name from sysobjects where name='sysmergesubscriptions')
  3628.         begin
  3629.         set @validsubs = 0
  3630.         return
  3631.         end
  3632.  
  3633.     /* Is there a valid non-loopback subscription? */
  3634.     if exists (select * from sysmergesubscriptions
  3635.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default)
  3636.         and subid <> partnerid)
  3637.         begin
  3638.         set @validsubs = 1
  3639.         return
  3640.         end
  3641.     /* Only possible subscriptions are loopbacks.  If database not enabled for publishing,
  3642.     ** then they don't indicate a valid publication/subscription. */
  3643.     if not exists (select name from master..sysdatabases where
  3644.         (category & 4) = 4 and name = db_name() collate database_default)
  3645.         begin
  3646.         set @validsubs = 0
  3647.         return
  3648.         end
  3649.     /* Database has merge publishing turned on, is probably a publisher.  Look for loopback
  3650.     ** subscription just to be sure... */
  3651.     if exists (select * from sysmergesubscriptions
  3652.         where db_name=db_name() and srvid = (select srvid from master..sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default))
  3653.         begin
  3654.         set @validsubs = 1
  3655.         return
  3656.         end
  3657.         
  3658.     /* Must not be valid... */    
  3659.     set @validsubs = 0
  3660.     return
  3661.  
  3662.  
  3663. GO
  3664.  
  3665.  
  3666. raiserror('Creating procedure sp_MSdrop_mergesystables', 0,1)
  3667. GO
  3668. create procedure sp_MSdrop_mergesystables as
  3669.  
  3670.     begin tran
  3671.     save transaction drop_mergesystables
  3672.     if exists (select * from sysobjects
  3673.         where name = 'sysmergearticles')
  3674.         begin
  3675.         drop table sysmergearticles
  3676.         end
  3677.     if @@error<>0
  3678.         goto Error
  3679.  
  3680.     if exists (select * from sysobjects
  3681.         where name = 'sysmergepublications')
  3682.         begin
  3683.         drop table sysmergepublications
  3684.         end
  3685.     if @@error<>0
  3686.         goto Error
  3687.  
  3688.     if exists (select * from sysobjects
  3689.         where name = 'sysmergesubscriptions')
  3690.         begin
  3691.         drop table sysmergesubscriptions
  3692.         end
  3693.     if @@error<>0
  3694.         goto Error
  3695.         
  3696.     if exists (select * from sysobjects
  3697.         where name = 'MSmerge_contents')
  3698.         begin
  3699.         drop table MSmerge_contents
  3700.         end
  3701.     if @@error<>0
  3702.         goto Error
  3703.  
  3704.     if exists (select * from sysobjects
  3705.         where name = 'MSmerge_replinfo')
  3706.         begin
  3707.         drop table MSmerge_replinfo
  3708.         end
  3709.     if @@error<>0
  3710.         goto Error
  3711.         
  3712.     if exists (select * from sysobjects
  3713.         where name = 'MSmerge_identity_range ')
  3714.         begin
  3715.         drop table MSmerge_identity_range 
  3716.         end
  3717.     if @@error<>0
  3718.         goto Error
  3719.  
  3720.  
  3721.     if exists (select * from sysobjects
  3722.         where name = 'MSmerge_tombstone')
  3723.         begin
  3724.         drop table MSmerge_tombstone
  3725.         end
  3726.     if @@error<>0
  3727.         goto Error
  3728.         
  3729.     if exists (select * from sysobjects
  3730.         where name = 'MSmerge_genhistory')
  3731.         begin
  3732.         drop table MSmerge_genhistory
  3733.         end
  3734.     if @@error<>0
  3735.         goto Error
  3736.         
  3737.     if exists (select * from sysobjects
  3738.         where name = 'MSmerge_delete_conflicts')
  3739.         begin
  3740.         drop table MSmerge_delete_conflicts
  3741.         end
  3742.     if @@error<>0
  3743.         goto Error
  3744.  
  3745.     if exists (select * from sysobjects
  3746.         where name = 'sysmergeschemachange')
  3747.         begin
  3748.         drop table sysmergeschemachange
  3749.         end
  3750.     if @@error<>0
  3751.         goto Error
  3752.  
  3753.     if exists (select * from sysobjects
  3754.         where name = 'sysmergesubsetfilters')
  3755.         begin
  3756.         drop table sysmergesubsetfilters
  3757.         end
  3758.     if @@error<>0
  3759.         goto Error
  3760.  
  3761.     if exists (select * from sysobjects
  3762.         where name = 'sysmergeschemaarticles')
  3763.         begin
  3764.         drop table sysmergeschemaarticles
  3765.         end
  3766.     if @@error<>0
  3767.         goto Error
  3768.         
  3769.     if exists (select * from sysobjects
  3770.         where name = 'MSmerge_errorlineage')
  3771.         begin
  3772.         drop table MSmerge_errorlineage
  3773.         end
  3774.     if @@error<>0
  3775.         goto Error
  3776.  
  3777.     if exists (select * from sysobjects
  3778.         where name = 'MSrepl_identity_range')
  3779.         begin
  3780.         drop table MSrepl_identity_range
  3781.         end
  3782.     if @@error<>0
  3783.         goto Error
  3784.     
  3785.     if exists (select * from sysobjects 
  3786.         where name = 'sysmergeextendedarticlesview')
  3787.         begin
  3788.         drop view sysmergeextendedarticlesview
  3789.         end
  3790.     if @@error<>0
  3791.         goto Error    
  3792.  
  3793.     if exists (select * from sysobjects
  3794.         where name = 'MSdynamicsnapshotjobs')
  3795.         begin
  3796.         drop table MSdynamicsnapshotjobs
  3797.         end
  3798.     if @@error<>0
  3799.         goto Error
  3800.  
  3801.     if exists (select * from sysobjects
  3802.         where name = 'MSmerge_altsyncpartners')
  3803.         begin
  3804.         drop table MSmerge_altsyncpartners
  3805.         end
  3806.     if @@error<>0
  3807.         goto Error
  3808.         
  3809.     if exists (select * from sysobjects
  3810.         where name = 'MSdynamicsnapshotviews')
  3811.         begin
  3812.         drop table MSdynamicsnapshotviews
  3813.         end
  3814.     if @@error<>0
  3815.         goto Error
  3816.  
  3817.     if exists (select * from master..sysobjects where type='P' and name='sp_MSremovedebuginfrastructure')
  3818.     begin
  3819.         declare @retval int
  3820.         exec @retval= dbo.sp_MSremovedebuginfrastructure
  3821.         if @@ERROR <> 0 or @retval <> 0 goto Error
  3822.     end
  3823.     
  3824.     commit transaction    
  3825.     return 0
  3826. Error:
  3827.     RAISERROR (20007, 16, -1)
  3828.     if @@trancount > 0
  3829.     begin
  3830.         ROLLBACK TRANSACTION drop_mergesystables
  3831.         COMMIT TRANSACTION
  3832.     end
  3833.     return 1
  3834. go
  3835.  
  3836. exec dbo.sp_MS_marksystemobject sp_MSdrop_mergesystables
  3837. go
  3838.  
  3839. raiserror ('Executing procedure dbo.sp_MSdrop_mergesystables.',0,1)
  3840. go
  3841. exec dbo.sp_MSdrop_mergesystables
  3842. go
  3843.  
  3844. dump tran master with no_log
  3845. go
  3846.  
  3847. raiserror('Creating procedure sp_MScreate_mergesystables',0,1)
  3848. GO
  3849. create procedure sp_MScreate_mergesystables as
  3850.  
  3851.     /* This is to make sure that the varbinary columns do not get padded */
  3852.  
  3853.     set ANSI_PADDING off
  3854.  
  3855.     DECLARE @exist bit 
  3856.     DECLARE @validsubs  int
  3857.     select @exist = 1
  3858.     
  3859.     begin tran
  3860.     save transaction MScreate_mergesystables
  3861.  
  3862.     exec dbo.sp_MScheckvalidsystables  @validsubs  output
  3863.     if @validsubs = 0
  3864.         exec dbo.sp_MSdrop_mergesystables
  3865.         
  3866.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  3867.         begin
  3868.  
  3869.             raiserror('Creating table sysmergepublications',0,1)
  3870.             
  3871.             create table dbo.sysmergepublications
  3872.             (    publisher                sysname NOT NULL default @@servername,
  3873.                 publisher_db            sysname NOT NULL default db_name(),
  3874.                 name                    sysname                NOT NULL,
  3875.                 description                nvarchar(255)         NULL,
  3876.                 retention                int                    NULL,
  3877.                 publication_type         tinyint                NULL,
  3878.                 pubid                     uniqueidentifier     NOT NULL,
  3879.                 designmasterid            uniqueidentifier     NULL,
  3880.                 parentid                uniqueidentifier     NULL,
  3881.                 sync_mode                tinyint                NULL,
  3882.                 allow_push                int                    NULL,
  3883.                 allow_pull                int                    NULL,
  3884.                 allow_anonymous            int                    NULL,
  3885.                 centralized_conflicts    int                    NULL,
  3886.                 status                    tinyint                NULL,
  3887.                 snapshot_ready            tinyint                NULL,
  3888.                 enabled_for_internet    bit                    NOT NULL default 0,
  3889.                 dynamic_filters            bit                    NOT NULL default 0,
  3890.                 -- portable snapshot support
  3891.                 snapshot_in_defaultfolder   bit             NOT NULL default 1,
  3892.                 alt_snapshot_folder         nvarchar(255)   NULL,
  3893.                 -- Pre/post - snapshot commands
  3894.                 pre_snapshot_script         nvarchar(255)   NULL,
  3895.                 post_snapshot_script        nvarchar(255)   NULL,
  3896.                 -- Snapshot compression
  3897.                 compress_snapshot           bit             NOT NULL default 0,
  3898.                 -- Post 7.0 Ftp support
  3899.                 ftp_address                 sysname         NULL,
  3900.                 ftp_port                    int             NOT NULL default 21,
  3901.                 ftp_subdirectory            nvarchar(255)   NULL,
  3902.                 ftp_login                   sysname         NULL default N'anonymous',
  3903.                 ftp_password                nvarchar(524)   NULL,
  3904.                 conflict_retention            int                NULL,
  3905.                 keep_before_values            int                NULL default 0,
  3906.                 allow_subscription_copy        bit             NULL default 0,     
  3907.                 allow_synctoalternate        bit             NULL default 0,
  3908.                 validate_subscriber_info    nvarchar(500)    NULL,
  3909.                 ad_guidname                    sysname            NULL,
  3910.                 backward_comp_level            int                not NULL default 10, --7.0 RTM
  3911.                 max_concurrent_merge        int                not NULL default 0,
  3912.                 max_concurrent_dynamic_snapshots int        not NULL default 0
  3913.             )
  3914.             if @@ERROR <> 0
  3915.                 goto Error
  3916.             
  3917.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergepublications 
  3918.                 ON sysmergepublications(pubid)
  3919.             if @@ERROR <> 0
  3920.                 goto Error
  3921.  
  3922.             exec dbo.sp_MS_marksystemobject sysmergepublications
  3923.             if @@ERROR <> 0
  3924.                 goto Error
  3925.             -- grant select on sysmergepublications to public
  3926.         end
  3927.  
  3928.     if not exists (select * from sysobjects where name = 'MSmerge_errorlineage')
  3929.         begin        
  3930.             raiserror('Creating table MSmerge_errorlineage',0,1)
  3931.             
  3932.             create table dbo.MSmerge_errorlineage (
  3933.             tablenick        int NOT NULL,
  3934.             rowguid            uniqueidentifier NOT NULL,
  3935.             lineage            varbinary(255)
  3936.             )
  3937.             exec dbo.sp_MS_marksystemobject MSmerge_errorlineage
  3938.             if @@ERROR <> 0
  3939.                 goto Error
  3940.             create unique clustered index uc1errorlineage on MSmerge_errorlineage(tablenick, rowguid)
  3941.             if @@ERROR <> 0
  3942.                 goto Error
  3943.             
  3944.             grant select on MSmerge_errorlineage to public
  3945.         end
  3946.  
  3947.     -- this table exists at distribution/db and subscriber databse both
  3948.     if not exists (select * from sysobjects where name = 'MSrepl_identity_range')
  3949.         begin        
  3950.             raiserror('Creating table MSrepl_identity_range',0,1)
  3951.             
  3952.             create table dbo.MSrepl_identity_range (
  3953.             objid                    int not NULL primary key,
  3954.             next_seed                bigint NULL, --resource control
  3955.             pub_range                bigint NULL, --publisher range
  3956.             range                    bigint NULL, -- set by sp_addmergearticle
  3957.             max_identity            bigint NULL, --resource control
  3958.             threshold                int    NULL,    --in percentage, set by sp_addmergearticle
  3959.             current_max                bigint NULL    --max value for current check constraint,set by sp_addmergearticle
  3960.             )
  3961.             exec dbo.sp_MS_marksystemobject MSrepl_identity_range
  3962.             if @@ERROR <> 0
  3963.                 goto Error
  3964.  
  3965.             grant select on MSrepl_identity_range to public
  3966.         end
  3967.  
  3968.     if not exists (select * from sysobjects where name = 'sysmergearticles')
  3969.         begin
  3970.         
  3971.             raiserror('Creating table sysmergearticles',0,1)
  3972.  
  3973.             
  3974.             create table dbo.sysmergearticles (
  3975.                 name                    sysname                NOT NULL,
  3976.                 type                    tinyint                NULL,
  3977.                 objid                    int                    NOT NULL, 
  3978.                 sync_objid                int                    NOT NULL,
  3979.                 view_type                 tinyint                NULL,
  3980.                 artid                    uniqueidentifier    NOT NULL,
  3981.                 description                nvarchar(255)        NULL,
  3982.                 pre_creation_command    tinyint                NULL,
  3983.                 pubid                    uniqueidentifier     NOT NULL,
  3984.                 nickname                int                    NOT NULL,
  3985.                 column_tracking            int                    NOT NULL,
  3986.                 status                    tinyint                NULL,
  3987.                 conflict_table            sysname                NULL,
  3988.                 creation_script            nvarchar(255)        NULL,
  3989.                 conflict_script            nvarchar(255)        NULL,
  3990.                 article_resolver        nvarchar(255)        NULL,
  3991.                 ins_conflict_proc        sysname                NULL,
  3992.                 insert_proc                sysname                NULL,
  3993.                 update_proc                sysname                NULL,
  3994.                 select_proc                sysname                NULL,
  3995.                 schema_option             binary(8)             NULL,
  3996.                 destination_object        sysname                NOT NULL,
  3997.                 destination_owner        sysname                NULL,
  3998.                 resolver_clsid            nvarchar(50)        NULL,
  3999.                 subset_filterclause        nvarchar(1000)      NULL,
  4000.                 missing_col_count        int                    NULL,
  4001.                 missing_cols            varbinary(128)        NULL,
  4002.                 excluded_cols            varbinary(128)        NULL,
  4003.                 excluded_col_count        int                    not NULL default 0,
  4004.                 columns                    varbinary(128)       NULL,
  4005.                 resolver_info            nvarchar(255)        NULL,
  4006.                 view_sel_proc            nvarchar(290)        NULL,
  4007.                 gen_cur                    int                    NULL,
  4008.                 vertical_partition        int                    not NULL default 0,
  4009.                 identity_support        int                    not NULL default 0,
  4010.                 before_image_objid        int                    NULL,
  4011.                 before_view_objid        int                    NULL,
  4012.                 verify_resolver_signature         int            NULL,
  4013.                 allow_interactive_resolver        bit            NOT NULL default 0,
  4014.                 fast_multicol_updateproc        bit            NOT NULL default 0,
  4015.                 check_permissions        int                    NOT NULL default 0,
  4016.                 maxversion_at_cleanup    int                    NOT NULL default 1
  4017.                 -- Note: Please update sysmergeextendedarticlesview whenever
  4018.                 -- there is a schema change in sysmergearticles
  4019.             )
  4020.         
  4021.             if @@error<>0
  4022.                 goto Error
  4023.             else
  4024.                 begin
  4025.                     
  4026.                     create unique clustered index uc1sysmergearticles
  4027.                         on sysmergearticles(artid, pubid) 
  4028.                     if @@ERROR <> 0
  4029.                         goto Error
  4030.                     
  4031.                     if not exists (select * from sysindexes where name = 'nc1sysmergearticles')
  4032.                     begin
  4033.                         create nonclustered index nc1sysmergearticles on sysmergearticles(nickname) 
  4034.                         if @@ERROR <> 0
  4035.                         return 1
  4036.                     end
  4037.                 end
  4038.             exec dbo.sp_MS_marksystemobject sysmergearticles
  4039.             if @@ERROR <> 0
  4040.                 goto Error
  4041.             grant select on sysmergearticles to public
  4042.             
  4043.         end
  4044.  
  4045.     if not exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  4046.         begin
  4047.             
  4048.             -- The extended merge articles table is for storing 
  4049.             -- schema only article information. 
  4050.             -- The current supported schema only articles are
  4051.             -- stored procs and views.
  4052.             raiserror('Creating table sysmergeschemaarticles',0,1)
  4053.  
  4054.             create table dbo.sysmergeschemaarticles 
  4055.             (   name                    sysname             NOT NULL,
  4056.                 type                    tinyint             NULL,
  4057.                 objid                   int                 NOT NULL,
  4058.                 artid                   uniqueidentifier    NOT NULL,
  4059.                 description             nvarchar(255)       NULL,
  4060.                 pre_creation_command    tinyint             NULL,
  4061.                 pubid                   uniqueidentifier    NOT NULL,
  4062.                 status                  tinyint             NULL,
  4063.                 creation_script         nvarchar(255)       NULL,
  4064.                 schema_option           binary(8)           NULL,
  4065.                 destination_object      sysname             NOT NULL,
  4066.                 destination_owner       sysname             NULL
  4067.                 -- Note: Please update sysmergeextendedarticlesview whenever
  4068.                 -- there is a schema change in sysmergeschemaarticles
  4069.             )
  4070.             
  4071.             if @@error<>0
  4072.                 goto Error
  4073.             else
  4074.                 begin
  4075.                     create unique clustered index uc1sysmergeschemaarticles
  4076.                         on sysmergeschemaarticles(artid, pubid)
  4077.                         if @@ERROR <> 0
  4078.                             goto Error
  4079.                 end
  4080.  
  4081.             exec dbo.sp_MS_marksystemobject sysmergeschemaarticles
  4082.             if @@ERROR <> 0
  4083.                 goto Error
  4084.  
  4085.         end
  4086.  
  4087.     if exists (select * from sysobjects where name = 'sysmergeextendedarticlesview')
  4088.     begin
  4089.         drop view dbo.sysmergeextendedarticlesview
  4090.     end
  4091.     exec ('create view dbo.sysmergeextendedarticlesview
  4092.                as
  4093.            select name, type, objid, sync_objid, view_type, artid, description, pre_creation_command, pubid,
  4094.                   nickname, column_tracking, status, conflict_table, creation_script, conflict_script, article_resolver,
  4095.                   ins_conflict_proc, insert_proc, update_proc, select_proc, schema_option, destination_object,
  4096.                   resolver_clsid, subset_filterclause, missing_col_count, missing_cols, columns, resolver_info,
  4097.                   view_sel_proc, gen_cur, excluded_cols, excluded_col_count, vertical_partition, identity_support,
  4098.                   destination_owner, before_image_objid, before_view_objid, verify_resolver_signature, 
  4099.                   allow_interactive_resolver, fast_multicol_updateproc, check_permissions, maxversion_at_cleanup
  4100.            from sysmergearticles
  4101.            union all
  4102.            select name, type, objid, NULL, NULL, artid, description, pre_creation_command, pubid, 
  4103.                   NULL, NULL, status, NULL, creation_script, NULL, NULL, 
  4104.                   NULL, NULL, NULL, NULL, schema_option, destination_object, 
  4105.                   NULL, NULL, NULL, NULL, NULL, NULL, 
  4106.                   NULL, NULL, NULL, NULL, NULL, NULL, 
  4107.                   destination_owner, NULL, NULL, NULL, 
  4108.                   0, 0, 0, NULL
  4109.                   from sysmergeschemaarticles
  4110.                   go')            
  4111.     if @@error <> 0
  4112.         goto Error
  4113.  
  4114.     exec dbo.sp_MS_marksystemobject sysmergeextendedarticlesview
  4115.  
  4116.     if not exists (select * from sysobjects    where name = 'sysmergesubscriptions')
  4117.         begin
  4118.         
  4119.             raiserror('Creating table sysmergesubscriptions',0,1)
  4120.  
  4121.             
  4122.             create table dbo.sysmergesubscriptions
  4123.             (
  4124.                 subid                 uniqueidentifier     NOT NULL,
  4125.                 partnerid             uniqueidentifier     NOT NULL,
  4126.                 datasource_type        int                    NOT NULL,
  4127.                 datasource_path        nvarchar(255)        NULL,
  4128.                 srvid                 int                    NOT NULL,
  4129.                 db_name                  sysname                 NOT NULL
  4130.                 constraint             unique_pubsrvdb     unique nonclustered (pubid, srvid, db_name),
  4131.                 pubid                uniqueidentifier     NULL,
  4132.                 status                tinyint             NOT NULL,
  4133.                 subscriber_type        int                    NOT NULL,
  4134.                 subscription_type    int                    NOT NULL,
  4135.                 priority            real                NOT NULL,
  4136.                 sync_type             tinyint                NOT NULL,    -- 1 = automatic 2 = no sync
  4137.                 description            nvarchar(255)        NULL,
  4138.                 login_name            sysname                NOT NULL,
  4139.                 last_validated        datetime            NULL,
  4140.                 subscriber_server    sysname                NULL,
  4141.                 use_interactive_resolver        bit        NOT NULL default 0,
  4142.                 publication            sysname                 NULL,
  4143.                 distributor            sysname                 NULL,
  4144.                 validation_level    int                    not NULL default 0,
  4145.                 resync_gen            int                    not NULL default -1,
  4146.                 attempted_validate    datetime            NULL,
  4147.                 last_sync_date        datetime            NULL,
  4148.                 last_sync_status    int                    NULL,
  4149.                 last_sync_summary    sysname                NULL
  4150.             )
  4151.         
  4152.             if @@error<>0
  4153.                 goto Error
  4154.             else
  4155.                 begin
  4156.                     create unique clustered index uc1sysmergesubscriptions 
  4157.                         on sysmergesubscriptions (subid) 
  4158.                     if @@ERROR<>0
  4159.                         goto Error
  4160.  
  4161.                     create index nc2sysmergesubscriptions on sysmergesubscriptions (srvid, db_name)
  4162.                     if @@ERROR<>0
  4163.                         goto Error
  4164.                 end
  4165.             exec dbo.sp_MS_marksystemobject sysmergesubscriptions
  4166.             if @@ERROR <> 0
  4167.                 goto Error
  4168.             grant select on sysmergesubscriptions to public
  4169.             
  4170.         end
  4171.  
  4172.     if not exists (select * from sysobjects    where name = 'MSmerge_replinfo')
  4173.         begin
  4174.             raiserror('Creating table MSmerge_replinfo',0,1)
  4175.             
  4176.             create table dbo.MSmerge_replinfo
  4177.             (
  4178.                 repid                     uniqueidentifier     NOT NULL,
  4179.                 replnickname            int                    NOT NULL,
  4180.                 recgen                    int                 NULL,
  4181.                 recguid                    uniqueidentifier     NULL,
  4182.                 sentgen                    int                 NULL,
  4183.                 sentguid                uniqueidentifier     NULL,
  4184.                 schemaversion            int                 NULL,
  4185.                 schemaguid                uniqueidentifier     NULL,
  4186.                 merge_jobid                binary(16)            NULL,
  4187.                 snapshot_jobid            binary(16)            NULL
  4188.             )
  4189.         
  4190.             if @@ERROR <> 0
  4191.                 goto Error
  4192.             else
  4193.                 begin
  4194.                     create unique clustered index uc1MSmerge_replinfo
  4195.                         on MSmerge_replinfo (repid)
  4196.                     if @@ERROR <> 0
  4197.                         goto Error
  4198.                 end
  4199.             exec dbo.sp_MS_marksystemobject MSmerge_replinfo
  4200.             if @@ERROR <> 0
  4201.                 goto Error
  4202.             grant select on MSmerge_replinfo to public
  4203.             
  4204.         end
  4205.  
  4206.     if not exists (select * from sysobjects    where name = 'MSmerge_tombstone')
  4207.         begin
  4208.             raiserror('Creating table MSmerge_tombstone',0,1)
  4209.             
  4210.             create table dbo.MSmerge_tombstone
  4211.             (
  4212.                 rowguid            uniqueidentifier rowguidcol NOT NULL,
  4213.                 tablenick        int                NOT NULL,
  4214.                 type            tinyint            NOT NULL,
  4215.                 lineage            varbinary(249)    NOT NULL,
  4216.                 generation        int                NOT NULL,
  4217.                 reason            nvarchar(255)    NOT NULL,
  4218.             )
  4219.  
  4220.             if @@ERROR <> 0
  4221.                 goto Error
  4222.             else
  4223.             begin
  4224.                 create unique clustered index uc1MSmerge_tombstone
  4225.                     on MSmerge_tombstone (tablenick DESC, rowguid) 
  4226.                 if @@ERROR <> 0    goto Error
  4227.                 
  4228.                 create index nc2MSmerge_tombstone
  4229.                     on MSmerge_tombstone (generation) 
  4230.                 if @@ERROR <> 0    goto Error
  4231.             end    
  4232.     
  4233.              exec dbo.sp_MS_marksystemobject MSmerge_tombstone
  4234.              if @@ERROR <> 0
  4235.                 goto Error
  4236.             grant select on MSmerge_tombstone to public
  4237.             
  4238.         end
  4239.  
  4240.     if not exists (select * from sysobjects    where name = 'MSmerge_contents')
  4241.         begin
  4242.             raiserror('Creating table MSmerge_contents',0,1)
  4243.             
  4244.             create table dbo.MSmerge_contents
  4245.             (
  4246.                 tablenick        int                    NOT NULL,
  4247.                 rowguid            uniqueidentifier rowguidcol   NOT NULL,
  4248.                 generation        int                    NOT NULL,
  4249.                 partchangegen    int                    NULL,
  4250.                 joinchangegen    int                    NULL,
  4251.                 lineage            varbinary(249)        NOT NULL,
  4252.                 colv1            varbinary(2048)        NULL,
  4253.             )
  4254.         
  4255.             if @@ERROR <> 0
  4256.                 goto Error
  4257.             else
  4258.             begin
  4259.                 create unique clustered index uc1SycContents on MSmerge_contents(tablenick, rowguid)
  4260.                 if @@ERROR <> 0 goto Error
  4261.                 create index nc2MSmerge_contents on MSmerge_contents(generation) 
  4262.                 if @@ERROR <> 0 goto Error
  4263.                 create index nc3MSmerge_contents on MSmerge_contents(partchangegen) 
  4264.                 if @@ERROR <> 0 goto Error
  4265.                 create index nc4MSmerge_contents on MSmerge_contents(rowguid) 
  4266.                 if @@ERROR <> 0 goto Error
  4267.             end
  4268.             exec dbo.sp_MS_marksystemobject MSmerge_contents
  4269.             if @@ERROR <> 0
  4270.                 goto Error
  4271.             grant select on MSmerge_contents to public
  4272.             
  4273.         end                
  4274.  
  4275.     if not exists (select * from sysobjects    where name = 'MSmerge_genhistory')
  4276.         begin
  4277.             raiserror('Creating table MSmerge_genhistory',0,1)
  4278.             
  4279.             create table dbo.MSmerge_genhistory
  4280.             (
  4281.                 guidsrc         uniqueidentifier     NOT NULL,
  4282.                 guidlocal         uniqueidentifier     NOT NULL,
  4283.                 pubid            uniqueidentifier     NULL,
  4284.                 generation         int                    NOT NULL,
  4285.                 art_nick        int                    NULL,
  4286.                 nicknames        varbinary(1000)        NOT NULL,
  4287.                 coldate         datetime            NOT NULL
  4288.             )
  4289.                     
  4290.             if @@ERROR <> 0
  4291.                 goto Error
  4292.  
  4293.             create clustered index c1MSmerge_genhistory on MSmerge_genhistory(generation) 
  4294.             if @@ERROR <> 0
  4295.                 goto Error
  4296.  
  4297.             create unique index unc1MSmerge_genhistory on MSmerge_genhistory(guidsrc, pubid) 
  4298.             if @@ERROR <> 0
  4299.                 goto Error
  4300.  
  4301.             create  index nc2MSmerge_genhistory on MSmerge_genhistory(guidlocal) 
  4302.             if @@ERROR <> 0
  4303.                 goto Error
  4304.  
  4305.             CREATE INDEX nc4MSmerge_genhistory ON MSmerge_genhistory(coldate)        
  4306.             if @@ERROR <> 0
  4307.                 goto Error
  4308.  
  4309.              exec dbo.sp_MS_marksystemobject MSmerge_genhistory
  4310.              if @@ERROR <> 0
  4311.                 goto Error
  4312.             grant select on MSmerge_genhistory to public
  4313.             
  4314.         end
  4315.  
  4316.     if not exists (select * from sysobjects    where name = 'MSmerge_delete_conflicts')
  4317.         begin
  4318.  
  4319.             raiserror('Creating table MSmerge_delete_conflicts',0,1)
  4320.             
  4321.             create table dbo.MSmerge_delete_conflicts
  4322.             (
  4323.                 tablenick            int                NOT NULL,
  4324.                 rowguid                uniqueidentifier rowguidcol NOT NULL,
  4325.                 origin_datasource    nvarchar(255)    NULL,
  4326.                 conflict_type        int NULL,
  4327.                 reason_code            int NULL,
  4328.                 reason_text            nvarchar(720)     NULL,
  4329.                 pubid                uniqueidentifier NULL,
  4330.                 create_time            datetime not null default getdate()
  4331.             )
  4332.         
  4333.             if @@ERROR <> 0
  4334.                 goto Error
  4335.             else
  4336.                 begin
  4337.                     create clustered index uc1MSmerge_delete_conflicts on MSmerge_delete_conflicts(tablenick, rowguid) 
  4338.                     if @@ERROR <> 0
  4339.                         goto Error
  4340.                 end                    
  4341.  
  4342.             CREATE UNIQUE NONCLUSTERED INDEX nc1MSmerge_delete_conflicts 
  4343.                     ON MSmerge_delete_conflicts(tablenick, rowguid, origin_datasource)
  4344.             if @@ERROR <> 0
  4345.                         goto Error
  4346.  
  4347.             exec dbo.sp_MS_marksystemobject MSmerge_delete_conflicts
  4348.             if @@ERROR <> 0
  4349.                 goto Error
  4350.             grant select on MSmerge_delete_conflicts to public
  4351.             
  4352.         end
  4353.  
  4354.     if not exists (select * from sysobjects    where name = 'sysmergeschemachange')
  4355.         begin
  4356.         
  4357.             raiserror('Creating table sysmergeschemachange',0,1)
  4358.             
  4359.             create table dbo.sysmergeschemachange
  4360.             (
  4361.                 pubid            uniqueidentifier     NOT NULL,
  4362.                 artid            uniqueidentifier     NULL,
  4363.                 schemaversion     int                NOT NULL,
  4364.                 schemaguid        uniqueidentifier     NOT NULL,
  4365.                 schematype        int                  NOT NULL,
  4366.                 schematext        nvarchar(2000)     NOT NULL
  4367.             )
  4368.         
  4369.             if @@ERROR <> 0
  4370.                 goto Error
  4371.             else
  4372.                 begin
  4373.                     create unique clustered index schemachangeversion on sysmergeschemachange(schemaversion, pubid) 
  4374.                     if @@ERROR <> 0
  4375.                         goto Error
  4376.                 end
  4377.             exec dbo.sp_MS_marksystemobject sysmergeschemachange
  4378.             if @@ERROR <> 0
  4379.                 goto Error
  4380.             grant select on sysmergeschemachange to public
  4381.             
  4382.         end
  4383.  
  4384.     if not exists (select * from sysobjects where name = 'sysmergesubsetfilters')
  4385.         begin
  4386.             raiserror('Creating table sysmergesubsetfilters',0,1)
  4387.  
  4388.             
  4389.             create table dbo.sysmergesubsetfilters (
  4390.                 filtername              sysname                 NOT NULL,
  4391.                 join_filterid            int                    identity NOT NULL,
  4392.                 pubid                    uniqueidentifier    NOT NULL,
  4393.                 artid                    uniqueidentifier    NOT NULL,
  4394.                 art_nickname            int                    NOT NULL,
  4395.                 join_articlename        sysname NOT NULL,
  4396.                 join_nickname             int                    NOT NULL,
  4397.                 join_unique_key            int                    NOT NULL,
  4398.                 expand_proc                sysname                    NULL,
  4399.                 join_filterclause        nvarchar(1000)          NULL
  4400.             )
  4401.             if @@ERROR <> 0
  4402.                 goto Error
  4403.  
  4404.             CREATE UNIQUE NONCLUSTERED INDEX nc1sysmergesubsetfilters 
  4405.                 ON sysmergesubsetfilters(join_filterid, pubid)
  4406.             if @@ERROR <> 0
  4407.                 goto Error
  4408.  
  4409.             exec dbo.sp_MS_marksystemobject sysmergesubsetfilters
  4410.             if @@ERROR <> 0
  4411.                 goto Error
  4412.             grant select on sysmergesubsetfilters to public
  4413.             
  4414.         end
  4415.  
  4416.     if @@error <> 0
  4417.         goto Error
  4418.  
  4419.     if not exists (select * from sysobjects where name = 'MSdynamicsnapshotviews')
  4420.         begin
  4421.             raiserror('Creating table MSdynamicsnapshotviews',0,1)
  4422.             
  4423.             create table dbo.MSdynamicsnapshotviews (
  4424.                 dynamic_snapshot_view_name sysname primary key
  4425.             )
  4426.             if @@ERROR <> 0
  4427.                 goto Error
  4428.             exec dbo.sp_MS_marksystemobject MSdynamicsnapshotviews
  4429.         end
  4430.  
  4431.     if not exists (select * from sysobjects where name = 'MSdynamicsnapshotjobs')
  4432.         begin
  4433.             raiserror('Creating table MSdynamicsnapshotjobs',0,1)
  4434.         
  4435.             create table dbo.MSdynamicsnapshotjobs (
  4436.                 id int identity, 
  4437.                 name sysname not null unique,
  4438.                 pubid uniqueidentifier not null,
  4439.                 job_id uniqueidentifier not null,
  4440.                 dynamic_filter_login sysname null,
  4441.                 dynamic_filter_hostname sysname null,
  4442.                 dynamic_snapshot_location nvarchar(255) not null
  4443.             )
  4444.             if @@ERROR <> 0
  4445.                 goto Error
  4446.  
  4447.             exec dbo.sp_MS_marksystemobject MSdynamicsnapshotjobs
  4448.  
  4449.             create unique clustered index uciMSdynamicsnapshotjobs on 
  4450.                 dbo.MSdynamicsnapshotjobs(job_id, pubid)
  4451.             
  4452.             if @@ERROR <> 0
  4453.                 goto Error
  4454.  
  4455.  
  4456.         end
  4457.     
  4458.     if @@error <> 0
  4459.         goto Error
  4460.  
  4461.     if not exists (select * from sysobjects where name = 'MSmerge_altsyncpartners')
  4462.         begin
  4463.             raiserror('Creating table MSmerge_altsyncpartners',0,1)
  4464.         
  4465.             create table dbo.MSmerge_altsyncpartners (
  4466.                 subid                 uniqueidentifier     not null,
  4467.                 alternate_subid     uniqueidentifier     not null,
  4468.                 description            nvarchar(255)        NULL
  4469.  
  4470.             )
  4471.             if @@ERROR <> 0
  4472.                 goto Error
  4473.  
  4474.             exec dbo.sp_MS_marksystemobject MSmerge_altsyncpartners
  4475.  
  4476.             create unique clustered index uciMSmerge_altsyncpartners on 
  4477.                 dbo.MSmerge_altsyncpartners(subid, alternate_subid)
  4478.             
  4479.             if @@ERROR <> 0
  4480.                 goto Error
  4481.  
  4482.  
  4483.         end
  4484.     
  4485.  
  4486.     if exists (select * from master..sysobjects where type='P' and name='sp_MScreatedebuginfrastructure')
  4487.     begin
  4488.         declare @retval int
  4489.         exec @retval= dbo.sp_MScreatedebuginfrastructure
  4490.         if @@ERROR <> 0 or @retval <> 0 goto Error
  4491.     end
  4492.     
  4493.     commit transaction
  4494.     return (0)
  4495. Error:
  4496.     if @@trancount > 0
  4497.     begin
  4498.         ROLLBACK TRANSACTION MScreate_mergesystables
  4499.         COMMIT TRANSACTION
  4500.     end
  4501.     RAISERROR (20008, 16, -1)
  4502.     return (1)
  4503. go
  4504.  
  4505. exec dbo.sp_MS_marksystemobject sp_MScreate_mergesystables 
  4506. go
  4507.  
  4508. raiserror('Creating procedure sp_MStestbit',0,1)
  4509. go
  4510. create procedure sp_MStestbit
  4511.             @bm varbinary(128),
  4512.             @coltotest smallint
  4513. AS
  4514.             declare @word smallint
  4515.             declare @bit  smallint
  4516.             declare @mask binary(2)
  4517.             declare @mval int
  4518.             declare @oldword binary(2)  
  4519.  
  4520.             if @coltotest < 1 return 0
  4521.  
  4522.             SELECT @word = 1 + FLOOR((@coltotest -1)/16)
  4523.  
  4524.             SELECT @bit = (@coltotest -1) % 16
  4525.  
  4526.             SELECT @mval = POWER(2, @bit)
  4527.             SELECT @mask = convert( binary(2), unicode( substring( convert( nchar(2), convert( binary(4), @mval ) ), 2, 1 ) ) )
  4528.             
  4529.             SELECT @oldword = convert( binary(2), SUBSTRING( convert( nvarchar(64),@bm), @word, 1) )
  4530.             IF @oldword IS NULL return 0
  4531.  
  4532.             return  convert( smallint, @oldword ) & convert( smallint, @mask )
  4533. go
  4534. exec dbo.sp_MS_marksystemobject sp_MStestbit
  4535. go
  4536. grant exec on dbo.sp_MStestbit to public
  4537.         
  4538. raiserror('Creating procedure sp_MSsetbit',0,1)
  4539. go
  4540. set ansi_padding on
  4541. go
  4542. create procedure sp_MSsetbit
  4543.     @bm varbinary(128) output,
  4544.     @coltoadd smallint,
  4545.     @toset    int = 1
  4546. AS
  4547.     declare @bytenum smallint
  4548.     declare @bit smallint
  4549.     declare @mask tinyint
  4550.     declare @newbyte tinyint     
  4551.     declare @oldbyte tinyint
  4552.             
  4553.     SELECT @bytenum = 1 + FLOOR((@coltoadd-1)/8)
  4554.  
  4555.     IF @bytenum > 128 return 0
  4556.  
  4557.     SELECT @bit = (@coltoadd-1) % 8
  4558.  
  4559.     SET @mask = POWER(2, @bit)
  4560.     if @toset = 0
  4561.         SET @mask = (~@mask % 256)
  4562.                 
  4563.     if @bm is null
  4564.         set @bm = 0x0
  4565.     while datalength(@bm) < @bytenum
  4566.         set @bm = @bm + 0x00 
  4567.  
  4568.     SET @oldbyte = SUBSTRING( @bm, @bytenum, 1)
  4569.     IF @oldbyte IS NULL SET @oldbyte = 0
  4570.     if @toset <> 0            
  4571.         SET @newbyte = @oldbyte | @mask
  4572.     else
  4573.         SET @newbyte = @oldbyte & @mask
  4574.  
  4575.     if (@bytenum = 1)
  4576.         set @bm = convert(binary(1), @newbyte) + substring(@bm, 2, 127)
  4577.     else
  4578.         set @bm = substring(@bm, 1, @bytenum - 1) + convert(binary(1), @newbyte) + substring(@bm, @bytenum + 1, 128 - @bytenum)
  4579. go
  4580. exec dbo.sp_MS_marksystemobject sp_MSsetbit
  4581. go
  4582. grant exec on dbo.sp_MSsetbit to public
  4583.  
  4584. raiserror('Creating procedure sp_MSinsertcontents',0,1)
  4585. go
  4586. create procedure sp_MSinsertcontents
  4587.                 @tablenick int,
  4588.                 @rowguid uniqueidentifier,
  4589.                  @lineage varbinary(249),
  4590.                  @colv1 varbinary(2048)
  4591. AS
  4592.                 /*
  4593.                 ** permission check
  4594.                 */
  4595.                 declare @retcode    int
  4596.                 declare @objid        int
  4597.                 declare @owner        sysname
  4598.                 declare @artid        uniqueidentifier
  4599.                 declare @guidstr    nvarchar(32)    
  4600.                 declare @instrigger nvarchar(270)
  4601.                 
  4602.                 select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  4603.                 select @owner =user_name(uid) from sysobjects where id=@objid
  4604.  
  4605.                 exec @retcode=sp_MSguidtostr @artid, @guidstr out
  4606.                     if @retcode<>0 or @@ERROR<>0 return (1)
  4607.  
  4608.                 set @instrigger = QUOTENAME(@owner) + '.ins_' + @guidstr
  4609.  
  4610.                 if trigger_nestlevel(object_id(@instrigger)) = 0
  4611.                 begin
  4612.                     raiserror(14126, 16, -1)
  4613.                     return (1) -- current user does not have insert permission to underlying table
  4614.                 end
  4615.             
  4616.                 insert into MSmerge_contents (tablenick, rowguid, generation, partchangegen, joinchangegen, lineage, colv1)
  4617.                     values (@tablenick, @rowguid, 0, 0, 0, @lineage, @colv1)
  4618.                 if @@error <> 0
  4619.                     begin
  4620.                     raiserror (20041, 16, -1)
  4621.                     return (1)
  4622.                     end            
  4623.  
  4624.                 delete from MSmerge_tombstone where rowguid = @rowguid and tablenick = @tablenick         
  4625.                 if @@error <> 0
  4626.                     begin
  4627.                     raiserror (20041, 16, -1)
  4628.                     return (1)
  4629.                     end    
  4630.  
  4631. go
  4632. exec dbo.sp_MS_marksystemobject sp_MSinsertcontents
  4633. go
  4634. grant exec on dbo.sp_MSinsertcontents to public
  4635.  
  4636. raiserror('Creating procedure sp_MSupdatecontents',0,1)
  4637. go
  4638. create procedure sp_MSupdatecontents
  4639.                  @tablenick int,
  4640.                  @rowguid uniqueidentifier,
  4641.                  @lineage varbinary(249),
  4642.                  @colv1 varbinary(2048),
  4643.                  @partchange int = null,
  4644.                  @joinchange int = null
  4645. AS
  4646.             /*
  4647.             ** permission check
  4648.             */
  4649.             declare @retcode    int
  4650.             declare @objid        int
  4651.             declare @owner        sysname
  4652.             declare @artid        uniqueidentifier
  4653.             declare @guidstr    nvarchar(32)    
  4654.             declare @updtrigger    nvarchar(270)
  4655.             
  4656.             select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  4657.             select @owner =user_name(uid) from sysobjects where id=@objid
  4658.             
  4659.             exec @retcode=sp_MSguidtostr @artid, @guidstr out
  4660.                     if @retcode<>0 or @@ERROR<>0 return (1)
  4661.                     
  4662.                 set @updtrigger = QUOTENAME(@owner) + '.upd_' + @guidstr
  4663.  
  4664.                 if trigger_nestlevel(object_id(@updtrigger)) = 0
  4665.                 begin
  4666.                     raiserror(14126, 16, -1)
  4667.                     return (1) -- current user does not 'update all' permission upon underlying table
  4668.                 end
  4669.             
  4670.             update MSmerge_contents set lineage = @lineage, generation = 0, colv1 = @colv1
  4671.                 where tablenick = @tablenick and rowguid = @rowguid
  4672.             if (@@rowcount = 0)
  4673.                 insert into MSmerge_contents (tablenick, rowguid, generation, joinchangegen, lineage, colv1)
  4674.                     values (@tablenick, @rowguid, 0, 1, @lineage, @colv1)
  4675.             if @@error <> 0
  4676.                 begin
  4677.                 raiserror (20041, 16, -1)
  4678.                 return (1)
  4679.                 end
  4680.             if @partchange = 1
  4681.                 begin
  4682.                 update MSmerge_contents set partchangegen = 0, joinchangegen = 0
  4683.                     where tablenick = @tablenick and rowguid = @rowguid
  4684.                 if @@error <> 0
  4685.                     begin
  4686.                     raiserror (20041, 16, -1)
  4687.                     return (1)
  4688.                     end
  4689.                 end
  4690.             else if @joinchange = 1
  4691.                 begin
  4692.                 update MSmerge_contents set joinchangegen = 0
  4693.                     where tablenick = @tablenick and rowguid = @rowguid
  4694.                 if @@error <> 0
  4695.                     begin
  4696.                     raiserror (20041, 16, -1)
  4697.                     return (1)
  4698.                     end
  4699.                 end 
  4700. go
  4701. exec dbo.sp_MS_marksystemobject sp_MSupdatecontents
  4702. go
  4703. grant exec on dbo.sp_MSupdatecontents to public
  4704.  
  4705. raiserror(15339, -1, -1, 'sp_MSdeletecontents')
  4706. go
  4707. create procedure sp_MSdeletecontents
  4708.     @tablenick int,
  4709.     @rowguid uniqueidentifier
  4710. AS
  4711.     declare @nick int
  4712.     declare @reason nvarchar(255)
  4713.     declare @lineage varbinary(255)
  4714.  
  4715.     /*
  4716.     ** permission check
  4717.     */
  4718.     declare @retcode    int
  4719.     declare @objid        int
  4720.     declare @owner        sysname
  4721.     declare @artid        uniqueidentifier
  4722.     declare @guidstr    nvarchar(32)    
  4723.     declare @deltrigger    nvarchar(270)
  4724.     declare @oldmaxversion int
  4725.     
  4726.     select @objid = objid, @artid=artid from sysmergearticles where nickname=@tablenick
  4727.     select @owner =user_name(uid) from sysobjects where id=@objid
  4728.     
  4729.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  4730.         if @retcode<>0 or @@ERROR<>0 return (1)
  4731.  
  4732.     set @deltrigger = QUOTENAME(@owner) + '.del_' + @guidstr
  4733.  
  4734.     if trigger_nestlevel(object_id(@deltrigger)) = 0
  4735.         begin
  4736.             raiserror(14126, 16, -1)
  4737.             return (1) -- current user does not have 'delete' permission to underlying table
  4738.         end
  4739.  
  4740.     exec dbo.sp_MSgetreplnick @nickname = @nick out
  4741.     if (@@error <> 0) or @nick IS NULL 
  4742.         begin
  4743.         RAISERROR (14055, 11, -1)
  4744.         RETURN(1)
  4745.         end                 
  4746.  
  4747.     select @oldmaxversion= maxversion_at_cleanup from sysmergearticles where nickname = @tablenick
  4748.     select @lineage = lineage from MSmerge_contents (UPDLOCK ROWLOCK index = 1) 
  4749.         where tablenick = @tablenick and rowguid = @rowguid
  4750.     set @lineage= { fn UPDATELINEAGE(@lineage, @nick, @oldmaxversion+1) }
  4751.     select @reason = 'user delete'
  4752.  
  4753.     insert into MSmerge_tombstone (rowguid, tablenick, type, lineage, generation, reason)
  4754.         values (@rowguid, @tablenick, 1, @lineage, 0, @reason)
  4755.     if @@error <> 0
  4756.         begin
  4757.         raiserror (20041, 16, -1)
  4758.         return (1)
  4759.         end
  4760.     delete from MSmerge_contents where
  4761.         tablenick = @tablenick and rowguid = @rowguid
  4762.     if @@error <> 0
  4763.         begin
  4764.         raiserror (20041, 16, -1)
  4765.         return (1)
  4766.         end 
  4767. go
  4768. exec dbo.sp_MS_marksystemobject sp_MSdeletecontents
  4769. go        
  4770. grant exec on dbo.sp_MSdeletecontents to public
  4771.  
  4772.  
  4773. raiserror('Creating procedure sp_MSunmarkifneeded',0,1)
  4774. GO
  4775.  
  4776. CREATE PROCEDURE sp_MSunmarkifneeded(
  4777. @object                sysname,
  4778. @pubid                uniqueidentifier,
  4779. @pre_command         int = 0,
  4780. @publisher            sysname,
  4781. @publisher_db        sysname
  4782. )AS
  4783. declare @table_in_use    int
  4784. declare @retcode         int
  4785.  
  4786. select @table_in_use = 0
  4787. --if pre-creation_command is 'drop (1)' or 'truncate (3)', then disallow this deployment if there is already an article using that table.
  4788. --other commands like 'delete, truncate, none are fine'
  4789.  
  4790. if exists (select * from sysmergearticles where objid=object_id(@object) and pubid in
  4791.     (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and 
  4792.         publisher_db=@publisher_db and pubid<>@pubid))
  4793.     OR
  4794.     ((@pre_command=1 or @pre_command=3) and 
  4795.         EXISTS (select * from sysmergearticles where objid=object_id(@object) and pubid <> @pubid and pubid not in
  4796.             (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@@SERVERNAME) and publisher_db=db_name())))  
  4797. begin
  4798.     select @table_in_use = 1
  4799.     select @table_in_use
  4800.     return (0)
  4801. end
  4802. exec @retcode = sp_MSunmarkreplinfo @object
  4803. if @retcode <>0 or @@error<>0
  4804.     return (1)
  4805. select @table_in_use 
  4806. return (0)
  4807. GO
  4808. exec dbo.sp_MS_marksystemobject sp_MSunmarkifneeded
  4809. go        
  4810. grant exec on dbo.sp_MSunmarkifneeded to public
  4811. go
  4812.  
  4813. raiserror('Creating procedure sp_MSunmarkreplinfo',0,1)
  4814. GO
  4815.  
  4816. CREATE PROCEDURE sp_MSunmarkreplinfo(
  4817.     @object                sysname,            /* Name of the table, unqualitied */
  4818.     @owner                sysname = NULL,            /* Name of the owner, unqualified */
  4819.     @type                smallint = 0        /* default is to unmark, as name implies */
  4820. )AS
  4821. declare @merge_pub_object_bit int
  4822. declare @merge_pub_unmark_bit int
  4823. declare @id    int
  4824. declare @qualified_name            nvarchar(270)
  4825. declare @retcode                int
  4826.  
  4827. exec @retcode = sp_MSreplcheck_subscribe
  4828. if @@error<>0 or @retcode<>0
  4829.     return (1)
  4830.  
  4831. if @owner is NULL or @owner=''
  4832.     select @owner = user_name(uid) from sysobjects where name=@object
  4833. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object) 
  4834.  
  4835.  
  4836. select @id = object_id(@qualified_name)
  4837.  
  4838. select @merge_pub_object_bit     = 128
  4839. select @merge_pub_unmark_bit = ~@merge_pub_object_bit
  4840.  
  4841. if exists (select name from sysobjects where id = @id) 
  4842.     begin
  4843.             if @type = 0    /* type = 0, unmark; else mark the bit */
  4844.         begin
  4845.             BEGIN TRANSACTION
  4846.                    exec dbo.sp_replupdateschema @qualified_name
  4847.                    update sysobjects set replinfo = replinfo & @merge_pub_unmark_bit where id = @id
  4848.                    exec dbo.sp_replupdateschema @qualified_name
  4849.             COMMIT TRANSACTION
  4850.         end
  4851.         else
  4852.         begin
  4853.             BEGIN TRANSACTION
  4854.                 exec dbo.sp_replupdateschema @qualified_name
  4855.                    update sysobjects set replinfo = replinfo | @merge_pub_object_bit where id = @id
  4856.                 exec dbo.sp_replupdateschema @qualified_name
  4857.                COMMIT TRANSACTION
  4858.         end
  4859.     end
  4860. GO
  4861. exec dbo.sp_MS_marksystemobject sp_MSunmarkreplinfo
  4862. go
  4863. grant execute on dbo.sp_MSunmarkreplinfo to public
  4864. go
  4865.  
  4866. /*
  4867. ** This is to have a better name 'sp_MSmarkreplinfo' while keeping the change minimal.
  4868. */
  4869. raiserror('Creating procedure sp_MSmarkreplinfo',0,1)
  4870. GO
  4871. CREATE PROCEDURE sp_MSmarkreplinfo(
  4872.     @object                sysname,            /* Name of the table, unqualitied */
  4873.     @owner                sysname = NULL        /* Name of the owner, unqualified */
  4874. )AS
  4875. declare @retcode int
  4876.  
  4877. exec @retcode = sp_MSunmarkreplinfo @object, @owner, 1
  4878. if @@ERROR<>0 or @retcode<>0
  4879.     return (1)
  4880. return (0)
  4881. GO
  4882. exec dbo.sp_MS_marksystemobject sp_MSmarkreplinfo
  4883. go
  4884. grant execute on dbo.sp_MSmarkreplinfo to public
  4885. go
  4886.  
  4887. raiserror('Creating procedure sp_MSunmarkschemaobject',0,1)
  4888. go
  4889. CREATE PROCEDURE sp_MSunmarkschemaobject(
  4890.     @object           sysname,     
  4891.     @owner            sysname = NULL
  4892. )AS
  4893. begin
  4894. set nocount on
  4895. declare @schema_obj_bit_mask int
  4896. declare @qualified_name nvarchar(520)
  4897. declare @id int
  4898. declare @retcode int
  4899.  
  4900. exec @retcode = sp_MSreplcheck_subscribe
  4901. if @@error<>0 or @retcode <>0
  4902.     return (1)
  4903.  
  4904. select @schema_obj_bit_mask = 0x00000200
  4905. select @schema_obj_bit_mask = ~@schema_obj_bit_mask
  4906.  
  4907. if (@owner is null or @owner = N'')
  4908. begin
  4909.     select @owner = user_name()
  4910. end
  4911. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object)
  4912.  
  4913. select @id = NULL
  4914. select @id = object_id(@qualified_name)
  4915.  
  4916. if (@id is not null)
  4917. begin
  4918.     begin transaction
  4919.     exec dbo.sp_replupdateschema @qualified_name
  4920.     update sysobjects set replinfo = replinfo & @schema_obj_bit_mask
  4921.     where id = @id
  4922.     exec dbo.sp_replupdateschema @qualified_name
  4923.     commit transaction
  4924. end
  4925. return 0    
  4926. end
  4927. go
  4928. exec dbo.sp_MS_marksystemobject sp_MSunmarkschemaobject
  4929. go
  4930. grant execute on dbo.sp_MSunmarkschemaobject to public
  4931. go
  4932.  
  4933. raiserror('Creating procedure sp_MSmarkschemaobject',0,1)
  4934. go
  4935. CREATE PROCEDURE sp_MSmarkschemaobject(
  4936.     @object           sysname,
  4937.     @owner            sysname = NULL
  4938. )AS
  4939. begin
  4940. set nocount on
  4941. declare @schema_obj_bit_mask int
  4942. declare @qualified_name nvarchar(520)
  4943. declare @id int
  4944. declare @retcode int
  4945.  
  4946. exec @retcode = sp_MSreplcheck_subscribe
  4947. if @@error<>0 or @retcode<>0
  4948.     return (1)
  4949.  
  4950. select @schema_obj_bit_mask = 0x00000200
  4951.  
  4952. if (@owner is null or @owner = N'')
  4953. begin
  4954.     select @owner = user_name()
  4955. end
  4956. select @qualified_name = QUOTENAME(@owner) + '.' + QUOTENAME(@object)
  4957.  
  4958. select @id = NULL
  4959. select @id = object_id(@qualified_name)
  4960.  
  4961. if (@id is not null)
  4962. begin
  4963.     begin transaction
  4964.     exec dbo.sp_replupdateschema @qualified_name
  4965.     update sysobjects set replinfo = replinfo | @schema_obj_bit_mask
  4966.     where id = @id
  4967.     exec dbo.sp_replupdateschema @qualified_name
  4968.     commit transaction
  4969. end
  4970. return 0
  4971. end
  4972. go
  4973. exec dbo.sp_MS_marksystemobject sp_MSmarkschemaobject
  4974. go
  4975. grant execute on dbo.sp_MSmarkschemaobject to public
  4976. go
  4977.  
  4978. raiserror('Creating procedure sp_MSaddanonymousreplica',0,1)
  4979. GO
  4980. CREATE PROCEDURE sp_MSaddanonymousreplica
  4981.     (@publication         sysname,
  4982.      @publisher            sysname,
  4983.      @publisherDB        sysname,
  4984.      @anonymous            int,
  4985.      @sync_type            int = 1, /* sync type is automatic by default */
  4986.      @preexists            bit=0 OUTPUT
  4987. )
  4988. as
  4989. set nocount on
  4990. declare @retcode                 int
  4991. declare @subscription_type         nvarchar(15)
  4992. declare @sync_typestr             nvarchar(15)
  4993. declare @sub_typeid                int
  4994. declare @pubid                    uniqueidentifier
  4995.  
  4996. select @preexists = 0
  4997.  
  4998. if @anonymous = 1 
  4999. begin
  5000.     select @subscription_type = 'anonymous'
  5001.     select @sub_typeid    = 2 --subscription type value for anonymous
  5002. end
  5003. else 
  5004. begin
  5005.     select @subscription_type = 'local'
  5006.     select @sub_typeid = 1 --subscription type value for well known pull
  5007. end
  5008.  
  5009. if @sync_type = 1 select @sync_typestr = 'automatic'
  5010.     else select @sync_typestr = 'none'
  5011.  
  5012. -- this change is made so that we will try to add pull/anonymous subscriptions, even if
  5013. -- there is a already a subscription for that publication, however the subscription type
  5014. -- does not match. In this way we can prevent users from using incorrect subscription type
  5015. -- through command line or merge control. 
  5016.  
  5017. if exists (select * from sysobjects where name='sysmergepublications')
  5018. begin
  5019.     select @pubid=pubid from sysmergepublications 
  5020.         where name=@publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisherDB
  5021.     if @pubid is not NULL
  5022.     begin
  5023.         /* Check if theres is a subscriptions entry that matches the pubid and current subscription with the right type */
  5024.         if exists (select * from sysmergesubscriptions where pubid =@pubid  and UPPER(subscriber_server) = @@SERVERNAME and db_name = DB_NAME() and subscription_type=@sub_typeid)
  5025.             begin
  5026.                 select @preexists = 1
  5027.                 return (0)   -- replica exists. 
  5028.             end
  5029.         /* 
  5030.         ** Check if theres is a subscriptions entry that matches the pubid and current subscription - 
  5031.         ** If there is a match and the types are not the same, then return appropriate error.
  5032.         */
  5033.         else if exists (select * from sysmergesubscriptions where pubid =@pubid  and UPPER(subscriber_server) = @@SERVERNAME and db_name = DB_NAME())
  5034.             begin
  5035.             RAISERROR (21500, 16, -1, @publication)    
  5036.             -- replica exists with wrong subscription type 
  5037.             select @preexists = 1
  5038.  
  5039.             return (1)   
  5040.             end
  5041.         
  5042.     end
  5043. end
  5044.  
  5045. -- Call this SP to add this replica
  5046. exec @retcode = dbo.sp_addmergepullsubscription 
  5047.     @publication = @publication,
  5048.     @publisher = @publisher,
  5049.     @publisher_db=@publisherDB,
  5050.     @subscriber_type =@subscription_type,
  5051.     @sync_type = @sync_typestr
  5052.  
  5053. IF @retcode<>0 or @@ERROR<>0 return (1)
  5054. return (0)
  5055. GO
  5056. exec dbo.sp_MS_marksystemobject sp_MSaddanonymousreplica
  5057. go
  5058. grant execute on dbo.sp_MSaddanonymousreplica to public
  5059. go 
  5060.  
  5061. raiserror('Creating procedure sp_MSgetreplicainfo',0,1)
  5062. GO
  5063. CREATE PROCEDURE sp_MSgetreplicainfo
  5064.     (@publisher            sysname,
  5065.      @publisher_db        sysname,
  5066.      @publication         sysname,
  5067.      @datasource_type    int = 0,                 /* 0 = SQL Server, 1 = DSN, 2 = Jet */
  5068.      @server_name        sysname    = NULL,         /* Server Name */
  5069.      @db_name            sysname = NULL,         /* Database Name */
  5070.      @datasource_path    nvarchar(255) = NULL)    /* Datasource path - JET MDB file path etc */
  5071.      
  5072. as
  5073.     declare        @srvid                int
  5074.     declare        @retcode            int
  5075.     declare        @repid                 uniqueidentifier
  5076.     declare        @pubid                 uniqueidentifier
  5077.     declare        @schemaguid            uniqueidentifier
  5078.     declare      @nickname             int
  5079.     declare     @subscription_type int
  5080.     declare     @validation_level    int
  5081.     declare     @reptype             tinyint
  5082.     declare     @priority             real 
  5083.     declare     @schversion         int 
  5084.     declare     @status                int
  5085.     declare     @resync_gen            int
  5086.     declare      @partnerid             uniqueidentifier
  5087.     declare     @sync_type             tinyint
  5088.     declare     @description         nvarchar(255)
  5089.     declare     @distributor        sysname
  5090.     
  5091.     /*
  5092.     ** Parameter Check:  @publication.
  5093.     ** Make sure that the publication exists.
  5094.     */
  5095.     if (@publication is null)
  5096.         begin
  5097.         RAISERROR(14043, 16, -1, '@publication')
  5098.         return (1)
  5099.         end
  5100.  
  5101.     if (@server_name is NULL)
  5102.         SET @server_name = @@SERVERNAME
  5103.  
  5104.     if (@db_name is NULL)
  5105.         set @db_name = db_name()
  5106.         
  5107.     SELECT @srvid = srvid FROM master..sysservers WHERE UPPER(srvname) = UPPER(@server_name) collate database_default
  5108.        IF @@ERROR <> 0
  5109.            BEGIN
  5110.             RAISERROR (14080, 16, -1)
  5111.              RETURN (1)
  5112.         END
  5113.  
  5114.     IF @srvid IS NULL
  5115.         BEGIN
  5116.             RAISERROR (14010, 16, -1)
  5117.             RETURN (1)
  5118.         END
  5119.  
  5120.     select @pubid = pubid from sysmergepublications 
  5121.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  5122.     if (@pubid is null)
  5123.         begin
  5124.             RAISERROR (20026, 16, -1, @publication)
  5125.             return (1)
  5126.         end
  5127.  
  5128.     if (@datasource_type = 0)
  5129.         begin
  5130.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  5131.                 @subscription_type = subscription_type , @status = status, 
  5132.                 @partnerid = partnerid, @sync_type = sync_type, 
  5133.                 @description = description, @distributor = distributor, 
  5134.                 @validation_level=validation_level, @resync_gen=resync_gen
  5135.                 FROM sysmergesubscriptions
  5136.                 WHERE srvid = @srvid and db_name = @db_name and pubid = @pubid
  5137.         END
  5138.     ELSE
  5139.         BEGIN
  5140.             SELECT @repid = subid, @priority = priority, @reptype = subscriber_type, 
  5141.                 @subscription_type = subscription_type , @status = status, 
  5142.                 @partnerid = partnerid, @sync_type = sync_type, 
  5143.                 @description = description,@distributor = distributor, 
  5144.                     @validation_level=validation_level, @resync_gen=resync_gen
  5145.                 FROM sysmergesubscriptions
  5146.                 WHERE srvid = @srvid and pubid = @pubid
  5147.         END
  5148.  
  5149.     if @repid is NULL
  5150.         begin
  5151.             RAISERROR(20021, 16, -1)
  5152.             return (1)
  5153.         end
  5154.     select @schversion = schemaversion, @schemaguid = schemaguid from MSmerge_replinfo where repid = @repid
  5155.     select @nickname = replnickname from MSmerge_replinfo where repid = @repid
  5156.     select @repid, @nickname, @reptype, @subscription_type, @priority, @schversion, @schemaguid,
  5157.         @status, @partnerid, @sync_type, @description, @publication, @distributor, @validation_level, @resync_gen
  5158.     return (0)
  5159. go
  5160. exec dbo.sp_MS_marksystemobject sp_MSgetreplicainfo
  5161. go
  5162. grant execute on dbo.sp_MSgetreplicainfo to public
  5163.  
  5164.  
  5165. raiserror('Creating procedure sp_MSadd_repl_job',0,1)
  5166. go
  5167.  
  5168. CREATE PROCEDURE sp_MSadd_repl_job
  5169.   @name                   nvarchar(200),
  5170.   @subsystem              nvarchar(60)  = 'TSQL',
  5171.   @server                 sysname  = NULL,
  5172.   @username               sysname  = NULL,
  5173.   @databasename           sysname  = NULL,
  5174.   @enabled                TINYINT      = 0,
  5175.   @freqtype               INT          = 2, -- 2 means OnDemand
  5176.   @freqinterval           INT          = 1,
  5177.   @freqsubtype            INT          = 1,
  5178.   @freqsubinterval        INT          = 1,
  5179.   @freqrelativeinterval   INT          = 1,
  5180.   @freqrecurrencefactor   INT          = 1,
  5181.   @activestartdate        INT          = 0,
  5182.   @activeenddate          INT          = 0,
  5183.   @activestarttimeofday   INT          = 0,
  5184.   @activeendtimeofday     INT          = 0,
  5185.   @nextrundate            INT          = 0,
  5186.   @nextruntime            INT          = 0,
  5187.   @runpriority            INT          = 0,
  5188.   @emailoperatorname      nvarchar(100) = NULL,
  5189.   @retryattempts          INT          = NULL,
  5190.   @retrydelay             INT          = 0,
  5191.   @command                nvarchar(4000)= NULL,
  5192.   @loghistcompletionlevel INT          = 2,
  5193.   @emailcompletionlevel   INT          = 0,
  5194.   @description            nvarchar(255) = NULL,
  5195.   @tagadditionalinfo      nvarchar(96)  = NULL,
  5196.   @tagobjectid            INT          = NULL,
  5197.   @tagobjecttype          INT          = NULL,
  5198.   @cmdexecsuccesscode     INT          = 0,
  5199.   @category_name          sysname = NULL, -- New for 7.0
  5200.   @failure_detection      BIT           = 0,
  5201.   @agent_id               INT           = NULL,
  5202.   @job_id BINARY(16) = NULL OUTPUT
  5203. AS
  5204. BEGIN
  5205.   DECLARE   @retval INT
  5206.   declare   @step_id int
  5207.   declare   @step_name nvarchar(100)
  5208.   declare   @step_command nvarchar(1024)
  5209.   declare   @on_fail_action tinyint
  5210.   declare   @on_success_action tinyint
  5211.   declare   @schedule_name nvarchar(100)
  5212.   declare   @comments nvarchar(100)
  5213.  
  5214.   SET NOCOUNT ON
  5215.  
  5216.   SELECT @retval = 1 -- 0 means success, 1 means failure
  5217.   set @step_id = 1
  5218.   set @on_fail_action = 2   -- Return failure
  5219.   set @on_success_action = 1    -- Return success
  5220.   set @step_command = NULL
  5221.  
  5222.   /*
  5223.   ** Set default retries to every minute for 10 minutes.
  5224.   **
  5225.   */
  5226.   if @retryattempts = NULL and @retrydelay = 0
  5227.   begin
  5228.      select @retryattempts = 10
  5229.      select @retrydelay = 1
  5230.   end
  5231.  
  5232.   BEGIN TRANSACTION
  5233.   save tran sp_MSadd_repl_job
  5234.  
  5235.     -- Drop the job if it already exists
  5236.     IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @name collate database_default)
  5237.     begin
  5238.         exec @retval = msdb.dbo.sp_delete_job @job_name=@name
  5239.         if @@ERROR<>0 or @retval<>0
  5240.             goto UNDO
  5241.     end
  5242.  
  5243.     -- Add the job
  5244.     EXECUTE @retval = msdb.dbo.sp_add_job
  5245.       @job_name                   = @name,
  5246.       @enabled                    = @enabled,
  5247.       @start_step_id              = 1,
  5248.       @description                = @description,
  5249.       @category_name              = @category_name,
  5250.       @notify_level_eventlog      = @loghistcompletionlevel,
  5251.       @notify_level_email         = @emailcompletionlevel,
  5252.       @notify_email_operator_name = @emailoperatorname,
  5253.       @job_id = @job_id OUTPUT
  5254.  
  5255.     IF (@retval <> 0)
  5256.     BEGIN
  5257.         GOTO UNDO
  5258.     END
  5259.  
  5260.     -- Add startup message step
  5261.     if @failure_detection = 1
  5262.     begin
  5263.  
  5264.         select @step_name = 
  5265.             case UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS)
  5266.                 when N'SNAPSHOT' then formatmessage(21410)
  5267.                 when N'LOGREADER' then formatmessage(20528)
  5268.                 when N'DISTRIBUTION' then formatmessage(21411)
  5269.                 when N'MERGE' then formatmessage(21412)
  5270.                 when N'QUEUEREADER' then formatmessage(21422)
  5271.             end 
  5272.         select @comments = formatmessage(20529)
  5273.  
  5274.         -- Construct command based on subsystem type
  5275.         select @step_command =
  5276.             case UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) 
  5277.                 WHEN 'SNAPSHOT' THEN
  5278.                 N'sp_MSadd_snapshot_history @perfmon_increment = 0,  @agent_id = ' + 
  5279.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5280.                     @comments = ''' + @comments + ''''
  5281.                 WHEN 'LOGREADER' THEN
  5282.                 N'sp_MSadd_logreader_history @perfmon_increment = 0, @agent_id = ' + 
  5283.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1, 
  5284.                     @comments = ''' + @comments + ''''
  5285.                 WHEN 'DISTRIBUTION' THEN
  5286.                 N'sp_MSadd_distribution_history @perfmon_increment = 0, @agent_id = ' + 
  5287.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5288.                     @comments = ''' + @comments + ''''
  5289.                 WHEN 'MERGE' THEN
  5290.                 N'sp_MSadd_merge_history @perfmon_increment = 0, @agent_id = ' + 
  5291.                     convert (nvarchar(10),@agent_id) + N', @runstatus = 1,  
  5292.                     @comments = ''' + @comments + ''''
  5293.                 WHEN 'QUEUEREADER' THEN
  5294.                 N'sp_MSadd_qreader_history @perfmon_increment = 0, @agent_id = ' + 
  5295.                     convert (nvarchar(10), @agent_id) + N', @runstatus = 1,  
  5296.                     @comments = ''' + @comments + ''''                  
  5297.             end
  5298.     
  5299.         -- Add the job step
  5300.         EXECUTE @retval = msdb.dbo.sp_add_jobstep
  5301.           @job_id                = @job_id,
  5302.           @step_id               = @step_id,
  5303.           @step_name             = @step_name,
  5304.           @command               = @step_command,
  5305.           @cmdexec_success_code  = @cmdexecsuccesscode,
  5306.           @on_success_action     = 3,   -- Goto next step
  5307.           @on_fail_action        = 3,   -- Goto next step
  5308.           @server                = @server,
  5309.           @database_name         = @databasename,
  5310.           @database_user_name    = @username,
  5311.           @os_run_priority       = @runpriority
  5312.  
  5313.         IF (@retval <> 0)
  5314.         BEGIN
  5315.             GOTO UNDO
  5316.         END
  5317.  
  5318.         set @step_id = @step_id + 1
  5319.         set @on_fail_action = 3         -- Goto next step
  5320.     end
  5321.  
  5322.     -- Add the job step
  5323.     select @step_name = formatmessage(20530)
  5324.     EXECUTE @retval = msdb.dbo.sp_add_jobstep
  5325.       @job_id                = @job_id,
  5326.       @step_id               = @step_id,
  5327.       @step_name             = @step_name,
  5328.       @subsystem             = @subsystem,
  5329.       @command               = @command,
  5330.       @cmdexec_success_code  = @cmdexecsuccesscode,
  5331.       @on_success_action     = @on_success_action,
  5332.       @on_fail_action        = @on_fail_action,
  5333.       @server                = @server,
  5334.       @database_name         = @databasename,
  5335.       @database_user_name    = @username,
  5336.       @retry_attempts        = @retryattempts,
  5337.       @retry_interval        = @retrydelay,
  5338.       @os_run_priority       = @runpriority
  5339.  
  5340.     IF (@retval <> 0)
  5341.     BEGIN
  5342.         GOTO UNDO
  5343.     END
  5344.  
  5345.     -- Add failure message step
  5346.     if @failure_detection = 1
  5347.     begin
  5348.  
  5349.         set @step_id = @step_id + 1
  5350.  
  5351.         select @step_name = formatmessage(20531)
  5352.  
  5353.         -- Construct command
  5354.         select @step_command = N'sp_MSdetect_nonlogged_shutdown @subsystem = ''' + @subsystem +  N''', @agent_id = ' + convert (nvarchar(10),   @agent_id) 
  5355.  
  5356.         -- Add the job step
  5357.         EXECUTE @retval = msdb.dbo.sp_add_jobstep
  5358.           @job_id                = @job_id,
  5359.           @step_id               = @step_id,
  5360.           @step_name             = @step_name,
  5361.           @command               = @step_command,
  5362.           @cmdexec_success_code  = @cmdexecsuccesscode,
  5363.           @on_success_action     = 2,                   -- Always quit with failure
  5364.           @server                = @server,
  5365.           @database_name         = @databasename,
  5366.           @database_user_name    = @username,
  5367.           @os_run_priority       = @runpriority
  5368.  
  5369.         IF (@retval <> 0)
  5370.         BEGIN
  5371.             GOTO UNDO
  5372.         END
  5373.     end
  5374.  
  5375.     -- Add the job schedule
  5376.     IF (@activestartdate = 0)
  5377.       SELECT @activestartdate = NULL
  5378.     IF (@activeenddate = 0)
  5379.       SELECT @activeenddate = NULL
  5380.     
  5381.     -- But if @activeenddate is NOT NULL, then @activestartdate cannot be allowed to be NULL either.  Set it to today's date converted to the int format used yyyymmdd
  5382.  
  5383.     IF (@activeenddate IS NOT NULL AND @activestartdate IS NULL)
  5384.     SELECT @activestartdate=DATEPART(YYYY,getdate()) * 10000 + DATEPART(MM,getdate()) * 100 + DATEPART(DD,getdate())
  5385.  
  5386.     -- But never let startdate be > end date
  5387.     IF (@activestartdate > @activeenddate)
  5388.     SELECT @activestartdate=@activeenddate
  5389.  
  5390.     IF (@activestarttimeofday = 0)
  5391.       SELECT @activestarttimeofday = NULL
  5392.     IF (@activeendtimeofday = 0)
  5393.       SELECT @activeendtimeofday = NULL
  5394.     IF (@freqtype <> 0x2) -- OnDemand tasks simply have no schedule in 7.0
  5395.     BEGIN
  5396.       select @schedule_name = formatmessage(20532)
  5397.  
  5398.       EXECUTE @retval = msdb.dbo.sp_add_jobschedule
  5399.         @job_id                 = @job_id,
  5400.         @name                   = @schedule_name,
  5401.         @enabled                = 1,
  5402.         @freq_type              = @freqtype,
  5403.         @freq_interval          = @freqinterval,
  5404.         @freq_subday_type       = @freqsubtype,
  5405.         @freq_subday_interval   = @freqsubinterval,
  5406.         @freq_relative_interval = @freqrelativeinterval,
  5407.         @freq_recurrence_factor = @freqrecurrencefactor,
  5408.         @active_start_date      = @activestartdate,
  5409.         @active_end_date        = @activeenddate,
  5410.         @active_start_time      = @activestarttimeofday,
  5411.         @active_end_time        = @activeendtimeofday
  5412.  
  5413.       IF (@retval <> 0)
  5414.       BEGIN
  5415.         GOTO UNDO
  5416.       END
  5417.     END
  5418.  
  5419.     -- And finally, add the job server
  5420.     EXECUTE @retval = msdb.dbo.sp_add_jobserver @job_id = @job_id, @server_name  = '(local)'
  5421.  
  5422.     IF (@retval <> 0)
  5423.     BEGIN
  5424.       GOTO UNDO
  5425.     END
  5426.  
  5427.   COMMIT TRANSACTION
  5428.  
  5429.   -- If this is an autostart LogReader or Distribution or Merge job, add the [new] '-Continuous' paramter to the command
  5430.   IF (@freqtype = 0x40) AND ((UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'LOGREADER') OR (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'DISTRIBUTION') OR 
  5431.             (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'MERGE') OR (UPPER(@subsystem collate SQL_Latin1_General_CP1_CS_AS) = 'QUEUEREADER'))
  5432.   BEGIN
  5433.     UPDATE msdb.dbo.sysjobsteps
  5434.     SET command = command + ' -Continuous'
  5435.     WHERE (job_id = @job_id)
  5436.       AND ((@failure_detection = 0 and step_id = 1) or (@failure_detection = 1 and step_id = 2))
  5437.   END  
  5438.  
  5439.   -- If this is an autostart job, start it now (for backwards compatibility with 6.x SQLExecutive behaviour)
  5440.   IF (@freqtype = 0x40)
  5441.     EXECUTE msdb.dbo.sp_start_job @job_id = @job_id, @error_flag = 0
  5442.  
  5443.   RETURN(0)
  5444.  
  5445. UNDO:
  5446.     rollback tran sp_MSadd_repl_job
  5447.     commit tran
  5448.     return(1)
  5449.  
  5450. END
  5451. go
  5452.  
  5453. raiserror('Creating procedure sp_MScheck_subscription', 0,1)
  5454. go
  5455.  
  5456. CREATE PROCEDURE sp_MScheck_subscription (
  5457. @publication    sysname,  --     1 Tran, 2 Merge
  5458. @pub_type        int
  5459. )AS
  5460. declare @merge_pubid    uniqueidentifier
  5461. declare @tran_pubid        int
  5462.  
  5463. if @pub_type = 2
  5464. BEGIN
  5465.     if not exists (select * from sysobjects where name = 'sysmergepublications')
  5466.         begin
  5467.             raiserror(20054, 16, -1)
  5468.             return (1)
  5469.         end
  5470.     select @merge_pubid = pubid from sysmergepublications where name=@publication and publisher=@@SERVERNAME and publisher_db=db_name()
  5471.     if @merge_pubid is NULL
  5472.         begin
  5473.             raiserror(20026, 16, -1, @publication)
  5474.             return (1)
  5475.         end
  5476.     if EXISTS (select * from sysmergesubscriptions where pubid=@merge_pubid and subid<>pubid)
  5477.         select 1
  5478.     else 
  5479.         select 0
  5480. END
  5481. else    -- if not merge, it has to be tran level. For other level, a generic error will be returned
  5482. BEGIN
  5483.     if not exists (select * from sysobjects where name='syspublications')
  5484.         begin
  5485.             raiserror(20054, 16, -1)
  5486.             return (1)
  5487.         end
  5488.     select @tran_pubid = pubid from syspublications where name=@publication
  5489.     if @tran_pubid is NULL 
  5490.         begin
  5491.             raiserror(20026, 16, -1, @publication)
  5492.             return (1)
  5493.         end
  5494.     if EXISTS (select * from syssubscriptions where (srvid <> -1) and artid in 
  5495.                        (select artid from sysextendedarticlesview where pubid=@tran_pubid))
  5496.           select 1
  5497.     else
  5498.            select 0
  5499. END
  5500. GO
  5501.  
  5502. exec dbo.sp_MS_marksystemobject sp_MScheck_subscription
  5503. go
  5504. grant execute on dbo.sp_MScheck_subscription to public
  5505. go
  5506.  
  5507. -- system procedure : returns string representing path to shared tools directory for 
  5508. -- the current instance as an output parm; if unable to get path, returns 1
  5509. raiserror(15339,-1,-1,'sp_MSgettools_path')
  5510. GO
  5511. CREATE PROCEDURE dbo.sp_MSgettools_path ( @install_path NVARCHAR(260) OUTPUT )
  5512. AS
  5513. BEGIN
  5514.     
  5515.     DECLARE @retcode INTEGER
  5516.     DECLARE @regkey NVARCHAR(260)
  5517.     DECLARE @len_minorversion tinyint
  5518.  
  5519.     SET NOCOUNT ON 
  5520.     
  5521.     SELECT @len_minorversion = 1 -- assume only 10's digit of minor version is significant
  5522.     SELECT @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\' + dbo.fn_MSsharedversion(@len_minorversion) + '\Tools\ClientSetup'
  5523.  
  5524.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  5525.         @regkey,
  5526.         'SQLPath',
  5527.         @param = @install_path OUTPUT
  5528.  
  5529.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) or ( @install_path IS NULL ) or ( @install_path = '' )
  5530.     BEGIN
  5531.         RETURN (1)
  5532.     END
  5533.  
  5534.     RETURN (0)
  5535.  
  5536. END
  5537. GO
  5538.  
  5539. raiserror('Creating procedure sp_replicationoption', 0,1)
  5540. go
  5541.  
  5542. CREATE PROCEDURE sp_replicationoption (
  5543. @optname        sysname,
  5544. @value            nvarchar(5),
  5545. @security_mode    int = 0,
  5546. @login            sysname = 'sa',
  5547. @password        sysname = NULL,
  5548. @reserved       nvarchar(20) = NULL
  5549. )
  5550. AS
  5551.     DECLARE @optbit bit
  5552.     DECLARE @osql_path nvarchar(260)
  5553.     DECLARE @osql_cmd1 nvarchar (255)
  5554.     DECLARE @osql_cmd_full nvarchar (255)
  5555.     DECLARE @osql_for_nt int
  5556.  
  5557.     DECLARE @install_path nvarchar (255)
  5558.  
  5559.     DECLARE @retcode int
  5560.     DECLARE @undo_install nvarchar(20)
  5561.     DECLARE @no_scripts nvarchar(10)
  5562.     DECLARE @platform_nt binary
  5563.     
  5564.     SELECT @platform_nt = 0x1
  5565.  
  5566.     if    is_srvrolemember('sysadmin') <> 1
  5567.         BEGIN
  5568.             RAISERROR (15232, 14, -1)
  5569.             RETURN (1)
  5570.         END
  5571.     
  5572.     SELECT @no_scripts = 'no_scripts'
  5573.  
  5574.     SELECT @undo_install = 'undo_install'
  5575.  
  5576.     IF db_name() <> 'master'
  5577.     BEGIN
  5578.         RAISERROR(5001, 16,-1)
  5579.         GOTO FAILURE
  5580.     END
  5581.  
  5582.     IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('transactional','merge')
  5583.     BEGIN
  5584.         RAISERROR(21014, 16, -1)
  5585.         GOTO FAILURE
  5586.     END
  5587.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  5588.     BEGIN
  5589.         RAISERROR(14137,16,-1)
  5590.         GOTO FAILURE
  5591.     END
  5592.     
  5593.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  5594.         SELECT @optbit = 1
  5595.     ELSE
  5596.         SELECT @optbit = 0
  5597.  
  5598.     /*
  5599.     ** Check if the option is set as required already
  5600.     */
  5601.     IF @reserved <> @undo_install AND EXISTS (SELECT * FROM MSreplication_options
  5602.         WHERE    optname  = @optname
  5603.         AND        value = @optbit)
  5604.     BEGIN
  5605.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  5606.             RAISERROR (21015, 10, -1, @optname)        
  5607.         ELSE
  5608.             RAISERROR (21016, 10, -1, @optname)
  5609.         GOTO FAILURE
  5610.     END
  5611.  
  5612.     /* Install replication */
  5613.     IF @optbit = 1
  5614.     BEGIN
  5615.  
  5616.         IF LOWER(@reserved collate SQL_Latin1_General_CP1_CS_AS) = @no_scripts
  5617.             GOTO NO_SCRIPTS
  5618.  
  5619.         -- Set the flag for platform
  5620.         IF (( platform() & @platform_nt = @platform_nt ))
  5621.             SELECT @osql_for_nt = 1
  5622.         ELSE
  5623.             SELECT @osql_for_nt = 0
  5624.  
  5625.         /* 
  5626.         ** Get installation path -- osql client (TOOLS) path
  5627.         */
  5628.         EXECUTE @retcode = master.dbo.sp_MSgettools_path @osql_path OUTPUT
  5629.         IF ( @@ERROR <> 0 ) OR ( @retcode <> 0 ) or ( @osql_path is NULL ) or ( @osql_path = '' )
  5630.         BEGIN
  5631.             GOTO FAILURE       
  5632.         END
  5633.  
  5634.         /* 
  5635.         ** Get installation path -- instance specific (INSTALL) directory
  5636.         */
  5637.         exec @retcode = master.dbo.sp_MSget_setup_paths
  5638.             @sql_path = @install_path output
  5639.         IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=''
  5640.             BEGIN
  5641.                 GOTO FAILURE       
  5642.             END
  5643.  
  5644.         /* 
  5645.         ** Install replcom.sql and repltran.sql
  5646.         */
  5647.         IF @security_mode = 1
  5648.         begin
  5649.             SELECT @osql_cmd1 = '"' + @osql_path + '\binn\osql" -E ' 
  5650.             if serverproperty('instancename') is not null
  5651.                 SELECT @osql_cmd1 = @osql_cmd1 + ' -S"' + @@SERVERNAME + '" '
  5652.         end
  5653.         ELSE
  5654.             -- cannot specify -S w/ -E for local execution, SID does not map
  5655.             SELECT @osql_cmd1 = '"' + @osql_path + '\binn\osql" -U"' + @login + '" -P"' + 
  5656.                 isnull(@password,'') + '" -S"' + @@SERVERNAME + '" '
  5657.  
  5658.         select @osql_cmd1 = @osql_cmd1 + '-l30 -t30 '
  5659.  
  5660.         -- Install replcom.sql 
  5661.         -- Only apply replcom.sql if it was not applied before.
  5662.         -- '-b' option will make osql stop at errors and return error code
  5663.         -- We must use this option.
  5664.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  5665.             WHERE value = 1)
  5666.         BEGIN
  5667.             -- Initialize the Command
  5668.             IF (@osql_for_nt = 1)
  5669.                 SELECT @osql_cmd_full = '" '
  5670.             ELSE
  5671.                 SELECT @osql_cmd_full = ' '
  5672.  
  5673.             SELECT @osql_cmd_full = @osql_cmd_full +
  5674.                 @osql_cmd1 + 
  5675.                 ' -dmaster' +  ' -b ' +
  5676.                 ' -i' + '"' + @install_path + '\install\replcom.sql"' + 
  5677.                 ' -o' + '"' + @install_path + '\install\replcom.out"' 
  5678.  
  5679.             IF (@osql_for_nt = 1)
  5680.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  5681.  
  5682.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  5683.             IF @@ERROR<> 0 OR @retcode <> 0
  5684.             BEGIN
  5685.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replcom.out')
  5686.                 GOTO UNDO_INSTALL     
  5687.             END
  5688.         END
  5689.  
  5690.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'transactional'
  5691.         BEGIN
  5692.             -- Install repltran.sql
  5693.             IF (@osql_for_nt = 1)
  5694.                 SELECT @osql_cmd_full = '" '
  5695.             ELSE
  5696.                 SELECT @osql_cmd_full = ' '
  5697.  
  5698.             SELECT @osql_cmd_full = @osql_cmd_full +
  5699.                 @osql_cmd1 + 
  5700.                 ' -dmaster' +  ' -b ' +
  5701.                 ' -i' + '"' + @install_path + '\install\repltran.sql"' + 
  5702.                 ' -o' + '"' + @install_path + '\install\repltran.out"' 
  5703.  
  5704.             IF (@osql_for_nt = 1)
  5705.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  5706.  
  5707.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full
  5708.             IF @@ERROR<> 0 OR @retcode <> 0
  5709.             BEGIN
  5710.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'repltran.out')
  5711.                 GOTO UNDO_INSTALL     
  5712.             END
  5713.  
  5714.         END
  5715.  
  5716.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge'
  5717.         BEGIN
  5718.             -- Install replmerg.sql 
  5719.             IF (@osql_for_nt = 1)
  5720.                 SELECT @osql_cmd_full = '" '
  5721.             ELSE
  5722.                 SELECT @osql_cmd_full = ' '
  5723.  
  5724.             SELECT @osql_cmd_full = @osql_cmd_full +
  5725.                 @osql_cmd1 + 
  5726.                 ' -dmaster' + ' -b ' +
  5727.                 ' -i' + '"' + @install_path + '\install\replmerg.sql"' + 
  5728.                 ' -o' + '"' + @install_path + '\install\replmerg.out"' 
  5729.             
  5730.             IF (@osql_for_nt = 1)
  5731.                 SELECT @osql_cmd_full = @osql_cmd_full + ' "'
  5732.  
  5733.             EXEC @retcode = master..xp_cmdshell @osql_cmd_full 
  5734.             
  5735.             IF  @@ERROR<> 0 OR @retcode <> 0
  5736.             BEGIN
  5737.                 RAISERROR (14113, 16, -1, @osql_cmd_full, 'replmerg.out')
  5738.                 GOTO UNDO_INSTALL     
  5739.             END
  5740.         END
  5741.  
  5742. NO_SCRIPTS:
  5743.  
  5744.         UPDATE MSreplication_options SET value = @optbit
  5745.             WHERE optname = @optname
  5746.         IF @@ERROR <> 0 
  5747.         BEGIN
  5748.             GOTO UNDO_INSTALL    
  5749.         END
  5750.  
  5751.     END
  5752.     /* Uninstall replication */
  5753.     ELSE
  5754.     BEGIN
  5755.  
  5756.         /* 
  5757.         ** Make sure no distributor installed before dropping 
  5758.         ** replication stored procedures
  5759.         */
  5760.         IF EXISTS (SELECT * FROM master..sysservers
  5761.               WHERE  srvstatus & 8 <> 0)
  5762.         BEGIN
  5763.             RAISERROR (21021, 16, -1)
  5764.             RETURN(1)
  5765.         END
  5766.  
  5767.         UPDATE MSreplication_options SET value = @optbit
  5768.             WHERE optname = @optname
  5769.         IF @@ERROR <> 0 
  5770.         BEGIN
  5771.             GOTO FAILURE
  5772.         END
  5773.  
  5774.         /* 
  5775.         *********** Do not drop replication stored procs anymore.
  5776.  
  5777.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'transactional'
  5778.         BEGIN
  5779.             if exists (select * from sysobjects
  5780.                 where type = 'P '
  5781.                         and name = 'sp_MSdrop_repltran')
  5782.             begin
  5783.                 exec @retcode = dbo.sp_MSdrop_repltran
  5784.                 if @@ERROR = 0 and @retcode = 0
  5785.                     drop procedure sp_MSdrop_repltran
  5786.             end
  5787.         END
  5788.  
  5789.         IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge'
  5790.         BEGIN
  5791.             if exists (select * from sysobjects
  5792.                 where type = 'P '
  5793.                         and name = 'sp_MSdrop_replmerg')
  5794.             begin
  5795.                 exec @retcode = dbo.sp_MSdrop_replmerg
  5796.                 if @@ERROR = 0 and @retcode = 0
  5797.                     drop procedure sp_MSdrop_replmerg
  5798.             end
  5799.         END
  5800.  
  5801.         IF NOT EXISTS (SELECT * FROM MSreplication_options
  5802.             WHERE value = 1)
  5803.         BEGIN
  5804.             if exists (select * from sysobjects
  5805.                 where type = 'P '
  5806.                         and name = 'sp_MSdrop_replcom')
  5807.             begin
  5808.                 exec @retcode = dbo.sp_MSdrop_replcom
  5809.                 if @@ERROR = 0 and @retcode = 0
  5810.                     drop procedure sp_MSdrop_replcom
  5811.             end
  5812.         END
  5813.  
  5814.         */
  5815.     END
  5816.  
  5817.     RETURN(0)
  5818.  
  5819. UNDO_INSTALL:
  5820.     /* This is needed to drop the stored procedures that were created. */
  5821.     EXEC dbo.sp_replicationoption @optname =  @optname, 
  5822.         @value = 'false', @reserved = @undo_install
  5823.  
  5824. FAILURE:
  5825.     RETURN(1)
  5826. GO
  5827. exec dbo.sp_MS_marksystemobject sp_replicationoption
  5828. go
  5829. grant execute on dbo.sp_replicationoption to public
  5830.     
  5831.  
  5832. raiserror('Creating procedure sp_helpreplicationoption', 0,1)
  5833. go
  5834.  
  5835. CREATE PROCEDURE sp_helpreplicationoption (
  5836. @optname        sysname = NULL
  5837. )
  5838. AS
  5839.     DECLARE @optbit bit
  5840.     DECLARE @retcode int
  5841.  
  5842.  
  5843.     IF @optname IS NOT NULL AND LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('transactional','merge')
  5844.     BEGIN
  5845.         RAISERROR(21014, 16, -1)
  5846.         GOTO FAILURE
  5847.     END
  5848.     
  5849.     SELECT optname, value, major_version, minor_version, revision 
  5850.         FROM master..MSreplication_options
  5851.         WHERE
  5852.             optname = @optname OR
  5853.             @optname = NULL
  5854.  
  5855.     RETURN(0)
  5856.  
  5857. FAILURE:
  5858.     RETURN(1)
  5859. GO
  5860. exec dbo.sp_MS_marksystemobject sp_helpreplicationoption
  5861. go
  5862. grant execute on dbo.sp_helpreplicationoption to public
  5863.  
  5864. raiserror('Creating procedure sp_MSgetreplnick', 0,1)
  5865. GO
  5866.  
  5867. create procedure sp_MSgetreplnick (
  5868.     @server        sysname = NULL,
  5869.     @db_name    sysname = NULL,
  5870.     @pubid        uniqueidentifier  = NULL,
  5871.     @nickname    int output
  5872.     )
  5873. as
  5874.     declare @srvid             int
  5875.     
  5876.     if @db_name IS NULL
  5877.         select @db_name = db_name()
  5878.  
  5879.     /* Use 0 if the Server name is not passed in since it would be the local server */
  5880.     if @server IS NULL
  5881.         select @srvid = 0
  5882.     else            
  5883.         select @srvid = max(srvid) from master..sysservers where UPPER(srvname) = UPPER(@server) collate database_default
  5884.  
  5885.     if (@pubid IS NOT NULL)
  5886.         begin
  5887.             select @nickname = max(replnickname) from MSmerge_replinfo 
  5888.                 where repid in (select subid from sysmergesubscriptions
  5889.                     where srvid = @srvid and db_name = @db_name and pubid = @pubid)
  5890.         end
  5891.     else
  5892.         begin
  5893.             select @nickname = max(replnickname) from MSmerge_replinfo 
  5894.                 where repid in (select subid from sysmergesubscriptions
  5895.                         where srvid = @srvid and db_name = @db_name)
  5896.         end
  5897. go
  5898.  
  5899. exec dbo.sp_MS_marksystemobject sp_MSgetreplnick
  5900. go
  5901. grant execute on dbo.sp_MSgetreplnick to public
  5902.  
  5903. raiserror('Creating procedure sp_MSreplcheck_publish', 0,1)
  5904. go
  5905.  
  5906. CREATE PROCEDURE sp_MSreplcheck_publish 
  5907. AS
  5908.     if    is_srvrolemember('sysadmin') <> 1  and
  5909.         is_member ('db_owner') <> 1
  5910.         BEGIN
  5911.             RAISERROR (21050, 14, -1)
  5912.             RETURN (1)
  5913.         END
  5914.     RETURN (0)
  5915. GO
  5916.  
  5917.  
  5918. raiserror('Creating procedure sp_MSlocktable', 0,1)
  5919. go
  5920. CREATE PROCEDURE sp_MSlocktable
  5921. @ownername        sysname,
  5922. @tablename        sysname
  5923. AS
  5924.     declare @retcode            int
  5925.     declare @procname            sysname
  5926.     declare @objid                 int
  5927.     declare @qualified_name        nvarchar(270)
  5928.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  5929.     select @objid = object_id(@qualified_name)
  5930.     if @objid is NULL
  5931.         select @objid = id from sysobjects where name=@tablename
  5932.     if @objid is null
  5933.         return (1)
  5934.     
  5935.     exec dbo.sp_MSreplcheck_connection @objid = @objid 
  5936.     
  5937.     select @procname = select_proc from sysmergearticles where objid = @objid and select_proc is not NULL
  5938.     exec @retcode = @procname @type = 7
  5939.     IF @@ERROR<>0 or @retcode<>0 RETURN (1)
  5940.  
  5941. --  exec ('select count(*) from ' + @ownername + '.' + @tablename + ' (tablock holdlock) where 1 = 2')
  5942. go
  5943. exec dbo.sp_MS_marksystemobject sp_MSlocktable
  5944. go
  5945. grant execute on dbo.sp_MSlocktable to public
  5946. go
  5947.  
  5948. raiserror('Creating procedure sp_MSenumcolumns', 0,1)
  5949. go
  5950. CREATE PROCEDURE sp_MSenumcolumns
  5951.     @pubid uniqueidentifier,
  5952.     @artid uniqueidentifier
  5953. AS
  5954.     declare @retcode            int
  5955.     declare @procname            sysname
  5956.     
  5957.     select @procname = select_proc from sysmergearticles where pubid = @pubid and artid = @artid
  5958.     exec @retcode = @procname @type =6
  5959.  
  5960. go
  5961. exec dbo.sp_MS_marksystemobject sp_MSenumcolumns
  5962. go
  5963. grant execute on dbo.sp_MSenumcolumns to public
  5964. go
  5965.  
  5966. /*
  5967. ** Get pubid through connection_ID and check permission of this publication
  5968. */
  5969.  
  5970. raiserror('Creating procedure sp_MSsetaccesslist', 0,1)
  5971. go
  5972. CREATE PROCEDURE sp_MSsetaccesslist
  5973. @publication     sysname,
  5974. @publisher         sysname,
  5975. @publisher_db    sysname
  5976. AS
  5977. declare @pubid uniqueidentifier
  5978. declare @retcode int
  5979.         select @pubid = pubid from sysmergepublications where 
  5980.                     name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  5981.         exec @retcode = dbo.sp_MSreplcheck_connection
  5982.             @publication = @publication,
  5983.             @pubid = @pubid,
  5984.             @is_init = 1
  5985.         if @retcode<>0 or @@ERROR<>0
  5986.             begin
  5987.                 return (1)
  5988.             end
  5989. go
  5990. exec dbo.sp_MS_marksystemobject sp_MSsetaccesslist
  5991. go
  5992. grant execute on dbo.sp_MSsetaccesslist to public
  5993. go
  5994.             
  5995. raiserror('Creating procedure sp_MSreplcheck_pull', 0,1)
  5996. go
  5997.  
  5998. CREATE PROCEDURE sp_MSreplcheck_pull (
  5999. @publication sysname,
  6000. @raise_fatal_error bit = 1,
  6001. @pubid uniqueidentifier = NULL,
  6002. @given_login sysname = NULL
  6003. )
  6004. AS
  6005.  
  6006.     declare @login sysname
  6007.  
  6008.     -- Bypass sa/dbo/cache optimizations if a login is explicitly provided
  6009.     if @given_login IS NULL or @given_login = N''
  6010.     begin
  6011.         -- sysadmin or db_owner have access
  6012.         if is_srvrolemember('sysadmin') = 1 or 
  6013.             is_member('db_owner') = 1
  6014.             return 0
  6015.  
  6016.         -- Need login_time to uniquely identify a connection.
  6017.         declare @login_time datetime
  6018.         select @login_time = login_time from master..sysprocesses where spid = @@spid
  6019.  
  6020.         -- If spid with publication in the cache, return success.
  6021.         if exists (select * from tempdb.dbo.MSpublisher_access where 
  6022.             spid = @@spid and
  6023.             login_time = @login_time and
  6024.             db_id = db_id() and
  6025.             publication = @publication)
  6026.             return (0)
  6027.         select @login = suser_sname(suser_sid())
  6028.     end
  6029.     else
  6030.     begin
  6031.         select @login = @given_login
  6032.     end
  6033.  
  6034.     declare @has_access bit
  6035.     DECLARE @distribdb sysname
  6036.     DECLARE @distproc nvarchar (300)
  6037.     DECLARE @retcode int
  6038.     DECLARE @dist_rpcname sysname
  6039.     DECLARE @database sysname
  6040.  
  6041.     select @database = db_name()
  6042.  
  6043.     EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  6044.                                            @distribdb   = @distribdb   OUTPUT
  6045.     IF @retcode <> 0 or @@error <> 0
  6046.     BEGIN
  6047.          RAISERROR (14071, 16, -1)
  6048.          return (1)
  6049.     END
  6050.  
  6051.     IF @retcode <> 0 OR @distribdb IS NULL OR @dist_rpcname IS NULL
  6052.     BEGIN
  6053.         RAISERROR (14071, 16, -1)
  6054.         return(1)
  6055.     END
  6056.  
  6057.     SELECT @distproc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  6058.     EXEC @retcode = @distproc
  6059.          @publisher = @@SERVERNAME,
  6060.          @publisher_db = @database,
  6061.          @publication = @publication,
  6062.          @operation = 'check',
  6063.          @login = @login,
  6064.          @has_access = @has_access output
  6065.  
  6066.     IF @@error <> 0 OR @retcode <> 0
  6067.         return (1)
  6068.  
  6069.     if @has_access = 0
  6070.     begin
  6071.  
  6072.         -- We don't have access if we reach here, return error
  6073.         IF @raise_fatal_error = 1
  6074.             RAISERROR (21049, 14, -1, @login, @publication)
  6075.         ELSE
  6076.             RAISERROR (21049, 10, -1, @login, @publication)
  6077.         return(1)
  6078.     end
  6079.  
  6080.     if @given_login is not null and @given_login <> N''
  6081.         return 0
  6082.  
  6083.  
  6084. ADD_CACHE:
  6085.  
  6086.     -- If we are here, we know that the connection has access and is not in the cache
  6087.     -- add it in to the cache.
  6088.         
  6089.     -- Clear the cache to keep it small.
  6090.     exec @retcode = dbo.sp_MSflush_access_cache
  6091.     if @retcode <> 0 or @@error <> 0
  6092.         return (1)
  6093.             
  6094.     insert tempdb.dbo.MSpublisher_access
  6095.         (spid, db_id, publication, login_time, pubid) values
  6096.         (@@spid, db_id(), @publication, @login_time, @pubid)
  6097.  
  6098.     if @@error <> 0
  6099.         return (1)
  6100.  
  6101.     return (0)
  6102. GO
  6103. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_pull
  6104. go
  6105. grant execute on dbo.sp_MSreplcheck_pull to public
  6106. go
  6107.  
  6108. raiserror('Creating procedure sp_MSreplcheck_connection', 0,1)
  6109. go
  6110.  
  6111. CREATE PROCEDURE sp_MSreplcheck_connection
  6112. @publication sysname = NULL,
  6113. @artid uniqueidentifier = NULL,
  6114. @repid uniqueidentifier = NULL,
  6115. @pubid uniqueidentifier = NULL,
  6116. @objid int                = NULL,
  6117. @tablenick int = NULL,
  6118. @is_init bit = 0
  6119. AS
  6120.     -- sysadmin or db_owner have access
  6121.     if is_srvrolemember('sysadmin') = 1 
  6122.         or is_member('db_owner') = 1 
  6123.         --or sessionproperty('replication_agent') = 1
  6124.         return 0
  6125.  
  6126.     declare @retcode int
  6127.     declare @cached_id uniqueidentifier
  6128.  
  6129.     -- Need login_time to uniquely identify a connection.
  6130.     declare @login_time datetime
  6131.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  6132.  
  6133.     select @cached_id = pubid from tempdb.dbo.MSpublisher_access where 
  6134.         spid = @@spid and
  6135.         login_time = @login_time
  6136.  
  6137.     -- If spid with publication in the cache, return success.
  6138.     if @cached_id is null
  6139.     begin
  6140.         -- This stored procedure might be called by common sprocs at
  6141.         -- both the publisher and the subscriber by the merge agent
  6142.         -- The merge agent will call this sp with @is_init = 1 before
  6143.         -- any other calls to the publisher. All the other calls will
  6144.         -- set @is_init to 0.
  6145.         if @is_init = 0
  6146.         begin
  6147.             RAISERROR (14126, 11, -1)
  6148.             return (1)
  6149.         end
  6150.         else
  6151.         begin
  6152.             exec @retcode = dbo.sp_MSreplcheck_pull @publication = @publication,
  6153.                 @pubid = @pubid
  6154.             if @retcode <> 0 or @@error <> 0
  6155.                 begin
  6156.                     return (1)
  6157.                 end
  6158.         end
  6159.     end
  6160.     else
  6161.     begin
  6162.         if @pubid is not null
  6163.         begin
  6164.             if @pubid <> @cached_id
  6165.             begin
  6166.                 RAISERROR (14126, 11, -1)
  6167.                 return (1)
  6168.             end
  6169.  
  6170.         end
  6171.         else if @tablenick is not null
  6172.         begin
  6173.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6174.                 nickname = @tablenick)
  6175.             begin
  6176.                 RAISERROR (14126, 11, -1)
  6177.                 return (1)
  6178.             end
  6179.         end
  6180.         else if @artid is not null
  6181.         begin
  6182.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6183.                 artid = @artid)
  6184.             begin
  6185.                 RAISERROR (14126, 11, -1)
  6186.                 return (1)
  6187.             end
  6188.         end
  6189.         else if @objid is not null
  6190.         begin
  6191.             if not exists (select * from sysmergearticles where pubid = @cached_id and 
  6192.                 objid=@objid)
  6193.             begin
  6194.                 RAISERROR (14126, 11, -1)
  6195.                 return (1)
  6196.             end
  6197.         end
  6198.         
  6199.         else if @publication is not null
  6200.         begin
  6201.             if not exists (select * from sysmergepublications where pubid = @cached_id and 
  6202.                 name = @publication)
  6203.             begin
  6204.                 RAISERROR (14126, 11, -1)
  6205.                 return (1)
  6206.             end
  6207.         end
  6208.         else if @repid is not null
  6209.         begin
  6210.             if not exists (select * from sysmergesubscriptions where pubid = @cached_id and 
  6211.                 subid = @repid)
  6212.             begin
  6213.                 RAISERROR (14126, 11, -1)
  6214.                 return (1)
  6215.             end
  6216.         end
  6217.     end
  6218. GO
  6219. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_connection
  6220. go
  6221. grant execute on dbo.sp_MSreplcheck_connection to public
  6222. go
  6223.  
  6224.  
  6225. raiserror('Creating procedure sp_MSreplcheck_qv', 0, 1)
  6226. GO
  6227.  
  6228. create procedure sp_MSreplcheck_qv
  6229. as
  6230. begin
  6231.  
  6232.     set nocount on 
  6233.         
  6234.     declare @qv_replication varchar(10)
  6235.     declare @qv_engine varchar(10)
  6236.     declare @qv_value_replication integer
  6237.     declare @qv_value_engine integer
  6238.  
  6239.     select @qv_replication = '2745196162', @qv_engine = '845129433'
  6240.  
  6241.     exec @qv_value_replication = master.dbo.sp_MSinstance_qv @qv_replication     
  6242.     if @@ERROR <> 0 
  6243.         select @qv_value_replication = 1
  6244.  
  6245.     exec @qv_value_engine = master.dbo.sp_MSinstance_qv @qv_engine
  6246.     if @@ERROR <> 0
  6247.         select @qv_value_engine = 1
  6248.  
  6249.     -- magic number 1 assumes least common setting on all failure states
  6250.     select isnull( @qv_value_replication, 1 ) as VALUE_REPLICATION, isnull( @qv_value_engine, 1 ) as VALUE_ENGINE
  6251.  
  6252.  
  6253. end
  6254. go
  6255.  
  6256. exec dbo.sp_MS_marksystemobject sp_MSreplcheck_qv
  6257. go    
  6258.  
  6259. grant execute on dbo.sp_MSreplcheck_qv to public
  6260. go
  6261.  
  6262. raiserror('Creating procedure sp_reinitmergepullsubscription', 0, 1)
  6263. GO
  6264.  
  6265. create procedure sp_reinitmergepullsubscription
  6266.     @publisher        sysname  = 'all',
  6267.     @publisher_db    sysname  = 'all',
  6268.     @publication    sysname  = 'all',
  6269.     @upload_first    nvarchar(5) = 'FALSE'
  6270. AS
  6271.     declare @schemaversion            int
  6272.     declare @schematype                smallint
  6273.     declare @schemaguid                uniqueidentifier
  6274.     declare @pubname                sysname
  6275.     declare @publisher_name            sysname
  6276.     declare @retcode                int
  6277.     declare @pubdb                    sysname
  6278.     declare @pubid                    uniqueidentifier
  6279.     declare @subid                    uniqueidentifier
  6280.     declare @artid                    uniqueidentifier
  6281.     /*
  6282.     ** Replace 'all' with '%'
  6283.     */
  6284.     set nocount on
  6285.     if LOWER(@publication) = 'all'
  6286.         SELECT @publication = '%'
  6287.  
  6288.     if LOWER(@publisher) = 'all'
  6289.         SELECT @publisher = '%'
  6290.  
  6291.     if LOWER(@publisher_db) = 'all'
  6292.         SELECT @publisher_db = '%'
  6293.     select @retcode = 0
  6294.     /*
  6295.     ** At subscriber side, we need to qualify the publication with server name and database name
  6296.     */
  6297.     IF NOT EXISTS (SELECT * FROM sysmergepublications WHERE name LIKE @publication 
  6298.         and ((@publisher = N'%') or (UPPER(publisher) = UPPER(@publisher))) 
  6299.         and ((@publisher_db = N'%') or (publisher_db = @publisher_db)) )
  6300.         
  6301.         BEGIN
  6302.         IF @publication = '%'
  6303.                 RAISERROR (14008, 11, -1)
  6304.         ELSE
  6305.                 RAISERROR (20026, 11, -1, @publication)
  6306.         RETURN (1)
  6307.         END
  6308.  
  6309.     if LOWER(@upload_first collate SQL_Latin1_General_CP1_CS_AS) not in ('true', 'false')
  6310.     begin
  6311.         raiserror(14148, 16, -1, '@upload_first')
  6312.         return (1)
  6313.     end
  6314.     Declare SYN_CUR CURSOR LOCAL FAST_FORWARD FOR 
  6315.         select subs.subid, pubs.name, pubs.publisher, pubs.publisher_db
  6316.             from sysmergepublications pubs, sysmergesubscriptions subs
  6317.                 where pubs.name LIKE  @publication
  6318.                     AND ((@publisher = '%') OR (UPPER(pubs.publisher) = UPPER(@publisher)))
  6319.                                         AND ((@publisher_db = N'%') OR (pubs.publisher_db = @publisher_db))
  6320.                     AND pubs.pubid=subs.pubid
  6321.                     AND subs.pubid<>subs.subid
  6322.     FOR READ ONLY
  6323.     open SYN_CUR
  6324.     fetch SYN_CUR into @subid, @pubname, @publisher_name, @pubdb
  6325.     while (@@fetch_status<>-1)
  6326.     BEGIN    
  6327.         
  6328.         -- do not update schemaversion if the initial snapshot has never been applied.
  6329.         update MSmerge_replinfo set schemaversion=-1, recgen = NULL, recguid=NULL, 
  6330.             sentgen=NULL, sentguid = NULL where repid=@subid and schemaversion is not null
  6331.  
  6332.         if (@@rowcount <> 0)
  6333.         begin
  6334.             if LOWER(@upload_first collate SQL_Latin1_General_CP1_CS_AS)='true'
  6335.                 update sysmergesubscriptions set status=5 where subid=@subid
  6336.             else
  6337.                 exec @retcode=sp_MSCleanupForPullReinit @publication=@pubname,
  6338.                                               @publisher=@publisher_name,
  6339.                                               @publisher_db=@pubdb
  6340.             if @retcode<>0 or @@ERROR<>0
  6341.             begin
  6342.                 return (1)
  6343.             end
  6344.         end
  6345.  
  6346.         fetch next from SYN_CUR into @subid, @pubname, @publisher_name, @pubdb    
  6347.             -- so that it won't be treated as a new susbscription    
  6348.     END
  6349.     close SYN_CUR
  6350.     deallocate SYN_CUR
  6351.     -- Forget that publisher ever sent us any generations.  They must be resent.
  6352.     -- Publication cleanup will remove the genhistory rows.
  6353.  
  6354.     if @publication = '%'
  6355.         -- get them all
  6356.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  6357.     else
  6358.         begin
  6359.         select @pubid = pubid from sysmergepublications where name = @publication
  6360.         update MSmerge_replinfo set recgen = NULL, recguid=NULL, sentgen=NULL, sentguid = NULL
  6361.             where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  6362.         end
  6363. GO
  6364.  
  6365. exec dbo.sp_MS_marksystemobject sp_reinitmergepullsubscription
  6366. go    
  6367. grant execute on dbo.sp_reinitmergepullsubscription to public
  6368. go
  6369. raiserror('Creating procedure sp_MSreplcheck_subscribe', 0,1)
  6370. go
  6371.  
  6372. CREATE PROCEDURE sp_MSreplcheck_subscribe
  6373. AS
  6374.     /*
  6375.     ** Only the System Administratr (SA) or the Database Owner (dbo) 
  6376.     ** can subscribe from the subscribing database.
  6377.     */
  6378.     if  is_srvrolemember('sysadmin') <> 1 and is_member ('db_owner') <> 1 
  6379.         BEGIN
  6380.             RAISERROR (21050, 14, -1)
  6381.             RETURN (1)
  6382.         END
  6383. GO
  6384.  
  6385. raiserror('Creating procedure sp_MSreplicationcompatlevel', 0,1)
  6386. GO
  6387. create procedure sp_MSreplicationcompatlevel
  6388. @dbname             sysname,
  6389. @cmptlevel            float(8)
  6390. As
  6391.     declare        @is_distdb    smallint
  6392.  
  6393.     select @is_distdb = 0
  6394.  
  6395.     IF EXISTS (select * from msdb..sysobjects where name='MSdistributiondbs')
  6396.         begin
  6397.             IF EXISTS (SELECT * FROM msdb..MSdistributiondbs where name=@dbname)
  6398.                 select @is_distdb = 1
  6399.         end
  6400.         
  6401.     /*
  6402.     ** Parameter check
  6403.     ** @dbname
  6404.     */
  6405.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  6406.         name = @dbname collate database_default)
  6407.     BEGIN
  6408.         RAISERROR(15010, 16, -1, @dbname)
  6409.         RETURN(2)
  6410.     END
  6411.  
  6412.     select @dbname = QUOTENAME(@dbname)
  6413.  
  6414.     /*
  6415.     ** Parameter check. NOTE
  6416.     ** @cmptlevel
  6417.     */
  6418.     IF @cmptlevel<6.0
  6419.     BEGIN
  6420.         RAISERROR(20060,16,-1)
  6421.         RETURN(2)
  6422.     END
  6423.  
  6424.     /*
  6425.     ** If cmptlevel is lower than 7.0, special attention should be paid. 
  6426.     ** If current database is a distribution database or is involed in merge
  6427.     ** replication, then it can not be set to a level lower than 7.0.
  6428.     */
  6429.     
  6430.     create table #tmp (any_merge smallint NOT NULL)
  6431.     insert into #tmp exec ('select count(*) from ' + @dbname + '..sysobjects where name=' + '''sysmergesubscriptions''' )
  6432.     if (exists(select any_merge from #tmp where any_merge>0) OR @is_distdb = 1) 
  6433.                 AND (@cmptlevel<7.0) 
  6434.         begin
  6435.             drop table #tmp
  6436.             return 1
  6437.         end
  6438.     else 
  6439.         begin
  6440.             drop table #tmp
  6441.             return 0
  6442.         end
  6443. go
  6444.  
  6445. exec dbo.sp_MS_marksystemobject sp_MSreplicationcompatlevel
  6446. go
  6447.  
  6448.  
  6449. raiserror('Creating procedure sp_MShelp_identity_property', 0,1)
  6450. GO
  6451.  
  6452. create procedure sp_MShelp_identity_property
  6453.             @tablename    sysname,
  6454.             @ownername    sysname = NULL
  6455. AS
  6456. declare @qualified_name        nvarchar(270)
  6457. declare @objid                int
  6458. declare @retcode            int
  6459. declare @proc                nvarchar(300)
  6460. declare @distributor        sysname
  6461. declare @distribdb            sysname
  6462. declare @publisher            sysname
  6463. declare @publisherdb        sysname
  6464. declare @pub_range            bigint
  6465. declare @sub_range            bigint
  6466. declare @threshold            int
  6467. declare @artid                int
  6468. declare @next_seed            bigint
  6469. declare @current_max        bigint
  6470. declare @replicated_already    bit
  6471. declare @auto_identity_support int
  6472. declare @identity_incr        int 
  6473. declare    @current_identity    bigint
  6474. declare @max_identity        bigint    
  6475. declare @xprec                int
  6476. declare @xtype                int
  6477. declare @republishing        bit
  6478. declare @length                int
  6479.  
  6480. select @replicated_already = 0
  6481. select @auto_identity_support = NULL
  6482.  
  6483. select @republishing = 0
  6484.  
  6485. select @pub_range    = NULL
  6486. select @sub_range    = NULL
  6487. select @threshold    = NULL
  6488. select @next_seed    = NULL
  6489. select @current_max    = NULL
  6490.  
  6491. if @ownername is not NULL
  6492. begin
  6493.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@tablename)
  6494.     select @objid = object_id(@qualified_name)
  6495. end
  6496. else
  6497. begin
  6498.     select @qualified_name = QUOTENAME(@tablename)
  6499.     select @objid = id from sysobjects where name=@tablename
  6500. end
  6501. if @objid is NULL
  6502. begin
  6503.     raiserror(14027, 16, -1, @tablename)
  6504.     return (1)
  6505. end
  6506.  
  6507. if OBJECTPROPERTY(@objid, 'tablehasidentity') <> 1
  6508.     begin
  6509.         raiserror(21194, 16, -1)
  6510.         return (1)
  6511.     end
  6512.  
  6513. select @xtype=xtype, @xprec=xprec, @length=length from syscolumns where id=@objid and columnproperty(id, name, 'IsIdentity')=1
  6514.  
  6515. select @max_identity = case @xtype 
  6516.                      when 52 then power((convert(bigint,2)), 8*2 -1) - 1 --smallint 
  6517.                      when 48 then power((convert(bigint,2)), 8 - 1) - 1          --tinyint
  6518.                      when 56 then power((convert(bigint,2)), 8*4 - 1) - 1          --int
  6519.                      when 127 then power((convert(bigint,2)), 62) -1 + power((convert(bigint,2)), 62)          --bigint
  6520.                         else power((convert(bigint,2)), 62) - 1 + power((convert(bigint,2)), 62)               --bigint;.
  6521.                     end
  6522.  
  6523. if (@xtype=108 or @xtype=106) and @xprec<18
  6524.     select @max_identity = power((convert(bigint,10)), (@xprec+1)) - 1
  6525.  
  6526. select @identity_incr = IDENT_INCR(@qualified_name)
  6527. select @current_identity =  ident_current(@qualified_name)
  6528.  
  6529. if exists (select * from sysobjects where name='sysmergearticles')
  6530.     begin
  6531.         if exists (select * from sysmergearticles where objid=@objid)
  6532.             begin
  6533.                 select @replicated_already = 1
  6534.                 select @auto_identity_support = identity_support from sysmergearticles where objid=@objid
  6535.                 if not exists (select * from sysmergearticles where objid=@objid and pubid in
  6536.                     (select pubid from sysmergepublications where publisher_db=db_name() 
  6537.                         and LOWER(publisher)=LOWER(@@SERVERNAME)))
  6538.                     select @republishing = 1
  6539.             end
  6540.     end    
  6541.  
  6542. if exists (select * from sysobjects where name='sysarticles')
  6543.     begin
  6544.         if exists (select * from sysarticles where objid=@objid)
  6545.             begin
  6546.                 select @replicated_already = 1
  6547.                 select @artid = artid from sysarticles where objid=@objid
  6548.                 select @auto_identity_support = identity_support from sysarticleupdates where artid=@artid
  6549.             end
  6550.     end
  6551.  
  6552. if @auto_identity_support is NOT NULL and @auto_identity_support=1
  6553. begin
  6554.     if @republishing = 0
  6555.     begin
  6556.         select @pub_range    = 0
  6557.         select @sub_range    = 0
  6558.         select @threshold    = 0
  6559.         select @next_seed    = 0
  6560.         select @current_max    = 0
  6561.         select @publisher=@@SERVERNAME
  6562.         select @publisherdb=db_name()
  6563.  
  6564.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @distributor OUTPUT,
  6565.             @distribdb   = @distribdb   OUTPUT
  6566.         IF @@error <> 0 OR @retcode <> 0
  6567.             RETURN (1)
  6568.  
  6569.         IF @distribdb is null
  6570.             BEGIN
  6571.                 RAISERROR (14071, 16, -1)
  6572.                 RETURN (1)
  6573.             END
  6574.                                      
  6575.         SELECT @proc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '.dbo.sp_MScheck_pub_identity'
  6576.         exec @retcode = @proc     @publisher=@publisher, 
  6577.                         @publisher_db=@publisherdb,  
  6578.                         @tablename=@tablename,
  6579.                         @current_max=@current_max OUTPUT,
  6580.                         @pub_range=@pub_range OUTPUT,
  6581.                         @range = @sub_range OUTPUT,
  6582.                         @threshold=@threshold OUTPUT,
  6583.                         @next_seed = @next_seed OUTPUT
  6584.         if @retcode<>0 or @@ERROR<>0
  6585.             return (1)
  6586.  
  6587.         -- Tran pub range is not stored at the distributor
  6588.         if @pub_range = 0
  6589.         begin
  6590.             if object_id('MSpub_identity_range') is not null
  6591.             begin
  6592.                 select @pub_range = pub_range from MSpub_identity_range where
  6593.                     objid = @objid 
  6594.             end
  6595.         end
  6596.     end
  6597.     else
  6598.     begin
  6599.         select @next_seed=next_seed, @max_identity=max_identity, @pub_range=(max_identity-next_seed)*2/10, 
  6600.                 @sub_range=(max_identity-next_seed)/10,
  6601.                 @threshold=80 from MSrepl_identity_range where objid=@objid
  6602.     end
  6603. end
  6604. SELECT 'replicated' = @replicated_already, 
  6605.        'auto_identity_support' = @auto_identity_support, 
  6606.        'identity_incremental' = @identity_incr, 
  6607.        'current_identity' = @current_identity,
  6608.        'next_starting_seed' = @next_seed, 
  6609.        'max_identity' = @max_identity, 
  6610.        'publisher_range' = ABS(@pub_range), 
  6611.        'subscriber_range' = ABS(@sub_range), 
  6612.        'threshold' = @threshold,
  6613.        'in_repulishing' = @republishing
  6614. GO
  6615. exec dbo.sp_MS_marksystemobject sp_MShelp_identity_property
  6616. go
  6617. grant execute on dbo.sp_MShelp_identity_property to public
  6618. GO
  6619.  
  6620. raiserror('Creating procedure sp_MSgenreplnickname', 0,1)
  6621. GO
  6622.  
  6623. create procedure sp_MSgenreplnickname
  6624.             @srcguid    uniqueidentifier,    /* Source Guid */
  6625.             @repnick    int    output    /* nickname */
  6626.     as
  6627.     declare @binguid binary(16)
  6628.     declare    @nickname        int
  6629.     set @binguid = convert(binary(16), @srcguid)
  6630.     select @nickname = convert(int, convert(binary(4),substring( convert(nchar(8),@binguid), 1, 2)))
  6631.     while exists (select replnickname from MSmerge_replinfo where replnickname = @nickname) or
  6632.             (@nickname > 0 and @nickname <= 256)
  6633.     begin
  6634.         select @nickname = @nickname + 1
  6635.     end
  6636.     select @repnick = @nickname
  6637. go
  6638.  
  6639. exec dbo.sp_MS_marksystemobject sp_MSgenreplnickname
  6640. go
  6641. grant execute on dbo.sp_MSgenreplnickname to public
  6642.  
  6643. raiserror('Creating procedure sp_MSmergesubscribedb', 0,1)
  6644. GO
  6645.  
  6646. CREATE PROCEDURE sp_MSmergesubscribedb(
  6647.     @value sysname
  6648.     ) AS
  6649.  
  6650.     SET NOCOUNT ON
  6651.  
  6652.     /*
  6653.     ** Declarations.
  6654.     */
  6655.     declare @retcode                 int
  6656.     
  6657.  
  6658.     /*
  6659.     ** Security Check
  6660.     */
  6661.  
  6662.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  6663.     IF @@ERROR <> 0 or @retcode <> 0
  6664.         RETURN(1)
  6665.  
  6666.  
  6667.     /*
  6668.     ** Initialization
  6669.     */
  6670.  
  6671.  
  6672.     /*
  6673.     ** Parameter check
  6674.     ** @value
  6675.     */
  6676.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  6677.     BEGIN
  6678.       RAISERROR(14137,16,-1)
  6679.       RETURN(1)
  6680.     END
  6681.  
  6682.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  6683.         BEGIN        
  6684.             execute @retcode = dbo.sp_MScreate_mergesystables
  6685.             if @@ERROR <> 0 or @retcode <> 0
  6686.                 begin
  6687.                     return (1)
  6688.                 end
  6689.         END
  6690.     
  6691.     -- We assume we will do nothing about disabling a subscriber
  6692.     
  6693. GO
  6694.  
  6695. exec dbo.sp_MS_marksystemobject sp_MSmergesubscribedb
  6696. go
  6697.  
  6698. grant execute on dbo.sp_MSmergesubscribedb to public
  6699. go 
  6700.  
  6701. raiserror('Creating procedure sp_MSenumallsubscriptions', 0,1)
  6702. go
  6703.  
  6704. CREATE PROCEDURE sp_MSenumallsubscriptions(
  6705. @subscription_type    nvarchar(5) = 'push', 
  6706. @subscriber_db        sysname='%'
  6707. )AS
  6708.  
  6709.     set nocount on
  6710.     declare @current_db        sysname
  6711.     declare @retcode        int
  6712.     declare @proc            nvarchar(200)
  6713.     declare @db_status        int
  6714.  
  6715.     create table #MSenumallsubscriptions (
  6716.                         publisher            sysname collate database_default not null,
  6717.                         publisher_db        sysname collate database_default not null,
  6718.                         publication            sysname collate database_default null,
  6719.                         replication_type    int not NULL,
  6720.                         subscription_type    int not NULL,
  6721.                         last_updated        datetime null,
  6722.                         subscriber_db        sysname collate database_default not null,
  6723.                         update_mode            smallint null,
  6724.                         last_sync_status    int null,
  6725.                         last_sync_summary    sysname collate database_default null,
  6726.                         last_sync_time        datetime null
  6727.                         )
  6728.  
  6729.     declare #cur_db cursor local FAST_FORWARD FOR select DISTINCT name, status
  6730.         FROM master.dbo.sysdatabases where ((@subscriber_db = N'%' collate database_default) or (name = @subscriber_db collate database_default)) and
  6731.             has_dbaccess(name) = 1
  6732.     open #cur_db
  6733.     fetch #cur_db into @current_db, @db_status
  6734.     while (@@fetch_status <> -1)
  6735.     begin
  6736.         /*
  6737.          * we only return subscriptions in db which is not in loading (0x20), suspect(0x100),
  6738.          * offline(0x200), in recovering(0x80), shutdown(0x40000), not recovered(0x40)
  6739.          */
  6740.         if (@db_status & 0x403e0) = 0
  6741.             begin
  6742.                 select @proc = QUOTENAME(@current_db) + '.' + 'dbo.sp_MSenumsubscriptions ' 
  6743.                 insert into #MSenumallsubscriptions exec @retcode = @proc  @subscription_type
  6744.                 if @@ERROR<>0 or @retcode<>0
  6745.                     begin
  6746.                         close #cur_db
  6747.                         deallocate #cur_db
  6748.                         return (1)
  6749.                     end
  6750.             end
  6751.         fetch next from #cur_db into @current_db, @db_status
  6752.     end
  6753.     select  distinct 'publisher'                = publisher,
  6754.             'publishing database'    = publisher_db,
  6755.             'publication'            = publication,
  6756.             'replication type'        = replication_type,
  6757.             'subscription type'     = subscription_type,
  6758.             'last updating time'    = convert(nvarchar(12), last_updated, 112) + 
  6759.                                           substring(convert(nvarchar(24), last_updated, 121), 11,13),
  6760.             'subscribing database'  = subscriber_db,
  6761.             'update_mode'           = update_mode,
  6762.             'last sync status'        = last_sync_status,
  6763.             'last sync summary'        = last_sync_summary,
  6764.             'last sync time'        = convert(nvarchar(12), last_sync_time, 112) + 
  6765.                 substring(convert(nvarchar(24), last_sync_time, 121), 11,13)
  6766.     from #MSenumallsubscriptions
  6767.     --drop table #MSenumallsubscriptions
  6768.     close #cur_db
  6769.     deallocate #cur_db
  6770.     return (0)
  6771. Go
  6772. grant execute on dbo.sp_MSenumallsubscriptions to public
  6773. go 
  6774. exec dbo.sp_MS_marksystemobject sp_MSenumallsubscriptions
  6775. GO
  6776.  
  6777. raiserror('Creating procedure sp_MSenumsubscriptions', 0,1)
  6778. go
  6779.  
  6780. CREATE PROCEDURE sp_MSenumsubscriptions(
  6781. @subscription_type    nvarchar(5) = 'push',
  6782. @publisher        sysname = '%',
  6783. @publisher_db     sysname = '%'
  6784. )AS
  6785.  
  6786.     set nocount on
  6787.     declare @dbname        sysname
  6788.     declare @category     int
  6789.     declare @proc            nvarchar(200)
  6790.     declare @retcode    int
  6791.     declare @cur_db        sysname
  6792.     declare @type_value    int
  6793.  
  6794.     select @type_value = 100
  6795.     
  6796.     if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='push'
  6797.         select @type_value = 0
  6798.     else
  6799.         if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='pull'
  6800.             select @type_value = 1
  6801.         else
  6802.             if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS)='both'
  6803.                 select @type_value = 2
  6804.  
  6805.     select @cur_db = db_name()
  6806.     
  6807.     create table #MSenumpushsubscriptions (
  6808.                         publisher            sysname collate database_default not null,
  6809.                         publisher_db        sysname collate database_default not null,
  6810.                         publication            sysname collate database_default null,
  6811.                         replication_type    int not NULL,
  6812.                         subscription_type    int not NULL,
  6813.                         last_updated        datetime null,
  6814.                         subscriber_db        sysname collate database_default not null,
  6815.                         update_mode            smallint null,
  6816.                         last_sync_status    int null,
  6817.                         last_sync_summary    sysname collate database_default null,
  6818.                         last_sync_time        datetime null
  6819.                         )
  6820.  
  6821.     if exists (select * from sysobjects where name='sysmergesubscriptions')
  6822.     begin
  6823.         -- return all subscriptions that this database is a subscriber to
  6824.         -- suppress all subscriptions that originate from this database.
  6825.         insert into #MSenumpushsubscriptions select p.publisher, p.publisher_db, p.name, 2, 
  6826.             s.subscription_type, s.last_sync_date, s.db_name, 
  6827.             NULL, s.last_sync_status, s.last_sync_summary, s.last_sync_date
  6828.             from sysmergepublications p, sysmergesubscriptions s
  6829.             where p.pubid = s.pubid 
  6830.             and (s.subscription_type=@type_value OR @type_value=2) 
  6831.             and s.pubid <> s.subid 
  6832.             and ((@publisher = N'%') or (p.publisher = @publisher))
  6833.                and ((@publisher_db = N'%') or ( p.publisher_db = @publisher_db))
  6834.             and s.db_name = @cur_db
  6835.             and p.pubid not in 
  6836.                 (select pubid from sysmergepublications pubs where 
  6837.                     lower(pubs.publisher) = LOWER(@@servername) AND
  6838.                     pubs.publisher_db = @cur_db)
  6839.     end
  6840.  
  6841.     if exists (select * from sysobjects where name='MSreplication_subscriptions')
  6842.     begin
  6843.         if  exists (select * from sysobjects where name='MSsubscription_properties') and
  6844.             exists (select * from sysobjects where name='MSsubscription_agents ') 
  6845.         begin
  6846.             -- update_mode in MSreplication_subscriptions table is not reliable.
  6847.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  6848.                 case isnull(p.publication_type,0) when 0 then 0 else 1 end,
  6849.                 s.subscription_type,
  6850.                 s.time, @cur_db, 
  6851.                 -- NOTE: For Queued case: we will always return 2/3 for the 4/5 case
  6852.                 -- since we overload update_mode based on queue_type
  6853.                 case when isnull(a.update_mode,0) = 4 then 2
  6854.                 when isnull(a.update_mode,0) = 5 then 3
  6855.                 else isnull(a.update_mode,0)
  6856.                 end,
  6857.                 a.last_sync_status,
  6858.                 a.last_sync_summary,
  6859.                 a.last_sync_time
  6860.                 from MSreplication_subscriptions s with (NOLOCK) 
  6861.                 left outer join MSsubscription_agents a with (NOLOCK) 
  6862.                     on (UPPER(s.publisher) = UPPER(a.publisher) and 
  6863.                         s.publisher_db = a.publisher_db and 
  6864.                         ((s.publication = a.publication and 
  6865.                         s.independent_agent = 1 and
  6866.                         a.publication <> N'ALL') or
  6867.                         (a.publication = N'ALL' and s.independent_agent = 0)) and
  6868.                         s.subscription_type = a.subscription_type)
  6869.                 left outer join MSsubscription_properties p with (NOLOCK)
  6870.                     on (UPPER(s.publisher) = UPPER(p.publisher) and 
  6871.                         s.publisher_db = p.publisher_db and 
  6872.                         s.publication = p.publication and
  6873.                         -- don't use property table for push. 
  6874.                         s.subscription_type <> 0) 
  6875.                 where
  6876.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  6877.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  6878.                     ((s.subscription_type = 0 and @type_value = 0) or
  6879.                     -- For pull, return both pull and anonymous
  6880.                     (s.subscription_type <> 0 and @type_value = 1) or
  6881.                     @type_value = 2) 
  6882.         end
  6883.         -- Property table does not exists.
  6884.         else if exists (select * from sysobjects where name='MSsubscription_agents ') 
  6885.         begin
  6886.             -- update_mode in MSreplication_subscriptions table is not reliable.
  6887.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  6888.                 -- Property table does not exists. Say transactional.
  6889.                 0,
  6890.                 s.subscription_type,
  6891.                 s.time, @cur_db, 
  6892.                 -- NOTE: For Queued case: we will always return 2/3 for the 4/5 case
  6893.                 -- since we overload update_mode based on queue_type
  6894.                 case when isnull(a.update_mode,0) = 4 then 2
  6895.                 when isnull(a.update_mode,0) = 5 then 3
  6896.                 else isnull(a.update_mode,0)
  6897.                 end,
  6898.                 a.last_sync_status,
  6899.                 a.last_sync_summary,
  6900.                 a.last_sync_time
  6901.                 from MSreplication_subscriptions s with (NOLOCK) 
  6902.                 left outer join MSsubscription_agents a with (NOLOCK) 
  6903.                     on (UPPER(s.publisher) = UPPER(a.publisher) and 
  6904.                         s.publisher_db = a.publisher_db and 
  6905.                         ((s.publication = a.publication and 
  6906.                         s.independent_agent = 1 and
  6907.                         a.publication <> N'ALL') or
  6908.                         (a.publication = N'ALL' and s.independent_agent = 0)) and
  6909.                         s.subscription_type = a.subscription_type)
  6910.                 where
  6911.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  6912.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  6913.                     ((s.subscription_type = 0 and @type_value = 0) or
  6914.                     -- For pull, return both pull and anonymous
  6915.                     (s.subscription_type <> 0 and @type_value = 1) or
  6916.                     @type_value = 2)             
  6917.         end
  6918.         -- Agents table does not exists.
  6919.         else if exists (select * from sysobjects where name='MSsubscription_properties ') 
  6920.         begin
  6921.             -- update_mode in MSreplication_subscriptions table is not reliable.
  6922.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  6923.                 case isnull(p.publication_type,0) when 0 then 0 else 1 end,
  6924.                 s.subscription_type,
  6925.                 s.time, @cur_db, 
  6926.                 s.update_mode,
  6927.                 NULL, --a.last_sync_status,
  6928.                 NULL, --a.last_sync_summary,
  6929.                 NULL  --a.last_sync_time    
  6930.                 from MSreplication_subscriptions s with (NOLOCK) 
  6931.                 left outer join MSsubscription_properties p with (NOLOCK)
  6932.                     on (UPPER(s.publisher) = UPPER(p.publisher) and 
  6933.                         s.publisher_db = p.publisher_db and 
  6934.                         s.publication = p.publication and
  6935.                         -- don't use property table for push. 
  6936.                         s.subscription_type <> 0) 
  6937.                 where
  6938.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  6939.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  6940.                     ((s.subscription_type = 0 and @type_value = 0) or
  6941.                     -- For pull, return both pull and anonymous
  6942.                     (s.subscription_type <> 0 and @type_value = 1) or
  6943.                     @type_value = 2) 
  6944.         end
  6945.         -- Both table does not exists
  6946.         else
  6947.         begin
  6948.             -- update_mode in MSreplication_subscriptions table is not reliable.
  6949.             insert into #MSenumpushsubscriptions select s.publisher, s.publisher_db, s.publication,
  6950.                 0,
  6951.                 s.subscription_type,
  6952.                 s.time, @cur_db, 
  6953.                 s.update_mode,
  6954.                 NULL, -- a.last_sync_status,
  6955.                 NULL, -- a.last_sync_summary
  6956.                 NULL  -- a.last_sync_time
  6957.                 from MSreplication_subscriptions s with (NOLOCK)
  6958.                 where
  6959.                     ((@publisher = N'%') OR (UPPER(s.publisher) = UPPER(@publisher))) AND
  6960.                     ((@publisher_db = N'%') or ( s.publisher_db = @publisher_db)) and
  6961.                     ((s.subscription_type = 0 and @type_value = 0) or
  6962.                     -- For pull, return both pull and anonymous
  6963.                     (s.subscription_type <> 0 and @type_value = 1) or
  6964.                     @type_value = 2) 
  6965.         end
  6966.     
  6967.     end
  6968.     select * from #MSenumpushsubscriptions
  6969.     --drop table #MSenumpushsubscriptions
  6970.     return (0)
  6971. GO
  6972.  
  6973. grant execute on dbo.sp_MSenumsubscriptions to public
  6974. go 
  6975. exec dbo.sp_MS_marksystemobject sp_MSenumsubscriptions
  6976. GO
  6977.  
  6978. raiserror('Creating procedure sp_MSenumallpublications', 0,1)
  6979. go
  6980.  
  6981. CREATE PROCEDURE sp_MSenumallpublications(
  6982. @publisherdb sysname = '%', 
  6983. @replication_type tinyint = null, -- by default return all types of publication
  6984. @agent_login sysname = NULL,
  6985. @security_check bit = 1, -- Security check by default so that things depending on security 
  6986.                         -- filtering will not break immediately
  6987. @vendor_name sysname = NULL,    -- Use vender name to filter the result of third party publications.
  6988. @publication sysname = NULL
  6989. )
  6990. as
  6991. BEGIN
  6992.     set nocount on
  6993.     declare @dbname         sysname
  6994.     declare @trans             tinyint
  6995.     declare @merge             tinyint
  6996.     declare @3rdparty        tinyint
  6997.     declare @retcode        int
  6998.     DECLARE @dist_rpcname    sysname
  6999.     declare @distribdb        sysname
  7000.     declare @login            sysname
  7001.     declare @proc            nvarchar(255)
  7002.     declare @distbit        int
  7003.     declare @is_user_admin    bit
  7004.     declare @same_as_user    bit
  7005.  
  7006.     -- UI: If the distributor is not installed, return empty result
  7007.     if not exists (SELECT * FROM master.dbo.sysservers
  7008.               WHERE  srvstatus & 8 <> 0)
  7009.         return (0)
  7010.  
  7011.     -- UI: Win95 subscriber will send in null agent_login
  7012.     -- Assume the agent login to be the current login if it is NT login
  7013.     if @security_check = 1 and @agent_login is null
  7014.         and not exists (select * from master.dbo.syslogins where
  7015.             sid = suser_sid() and 
  7016.             isntname = 0)
  7017.         select @agent_login = suser_sname(suser_sid())
  7018.  
  7019.     /* Initializations */
  7020.     select @trans = 1 
  7021.     select @merge = 2
  7022.     select @3rdparty = 0
  7023.     select @login = suser_sname(suser_sid())
  7024.     SELECT @distbit = 16
  7025.     select @is_user_admin = 0
  7026.     select @same_as_user = 0
  7027.  
  7028.     -- Get publication list
  7029.     create table #pubdbs (publisher_db sysname collate database_default not null, replication_type int NOT NULL)
  7030.     create table #MSenumpublications 
  7031.             (publisher_db sysname collate database_default not null, publication sysname collate database_default not null, replication_type tinyint NOT NULL, 
  7032.             immediate_sync bit NOT NULL, allow_pull bit NOT NULL, allow_anonymous bit NOT NULL, 
  7033.             enabled_for_internet bit NOT NULL, repl_freq tinyint NOT NULL, immediate_sync_ready bit NOT NULL, 
  7034.             allow_sync_tran bit NOT NULL, independent_agent bit NOT NULL, is_db_owner int NOT NULL, 
  7035.             thirdparty_flag bit NOT NULL, vendor_name sysname collate database_default null, publisher sysname collate database_default null, 
  7036.             description nvarchar(255) collate database_default null, distribution_db sysname collate database_default null, 
  7037.             allow_queued_tran bit not null, allow_dts bit not null, thirdparty_options int null,
  7038.             queue_type int null, dynamic_filters bit not null default 0)
  7039.     create table #admin_publications (publisher_db sysname collate database_default not null, 
  7040.         publication sysname collate database_default not null)
  7041.     create table #agent_publications (publisher_db sysname collate database_default not null,
  7042.         publication sysname collate database_default not null)
  7043.  
  7044.     /* Return everything if @replication_type is not in (@3rdparty, @trans, @merge) */
  7045.     if not @replication_type in (@3rdparty, @trans, @merge)
  7046.         select @replication_type = null
  7047.  
  7048.     if @replication_type = @trans or @replication_type is null
  7049.         insert into #pubdbs select name, @trans from master.dbo.sysdatabases where 
  7050.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & 1 <> 0 and 
  7051.             has_dbaccess(name) = 1
  7052.     if @replication_type = @merge or @replication_type is null
  7053.         insert into #pubdbs select name, @merge from master.dbo.sysdatabases where 
  7054.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & 4 <> 0 and 
  7055.             has_dbaccess(name) = 1
  7056.     if @replication_type = @3rdparty
  7057.         insert into #pubdbs select name, @3rdparty from master.dbo.sysdatabases where 
  7058.             ((@publisherdb = N'%') or ( name = @publisherdb collate database_default)) and category & @distbit <> 0 and 
  7059.             has_dbaccess(name) = 1
  7060.  
  7061.     declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db, replication_type from  #pubdbs
  7062.     FOR READ ONLY
  7063.     open hCForEachDb
  7064.     fetch hCForEachDb into @dbname, @replication_type
  7065.     /* Loop for each database */
  7066.     while (@@fetch_status >= 0) 
  7067.     begin
  7068.         if (@replication_type) = @trans
  7069.             select @proc = quotename(@dbname) + '.dbo.sp_MSenumtranpublications'
  7070.         else if (@replication_type) = @merge
  7071.             select @proc = quotename(@dbname) + '.dbo.sp_MSenummergepublications'
  7072.         else if (@replication_type) = @3rdparty
  7073.             select @proc = quotename(@dbname) + '.dbo.sp_MSenum3rdpartypublications'
  7074.         if (@replication_type) = @3rdparty
  7075.             insert into #MSenumpublications exec @retcode = @proc @vendor_name, @publication
  7076.         else
  7077.             insert into #MSenumpublications exec @retcode = @proc @publication
  7078.  
  7079.         if @@ERROR <> 0 or @retcode <> 0
  7080.             return (1)
  7081.         fetch hCForEachDb into @dbname, @replication_type
  7082.     end /* while FETCH_SUCCESS */
  7083.  
  7084.     -- Prepare for filtering.
  7085.     IF EXISTS (SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistpublishers' and xtype = 'U') -- this is the distributor, check if publisher too
  7086.         if not exists (select * from msdb.dbo.MSdistpublishers where upper(name) = upper(@@SERVERNAME) collate database_default) -- not publisher
  7087.             select @security_check = 0     -- no need to go through security check for none-publisher 
  7088.                             -- since it won't have any publication other than third party ones.
  7089.                             
  7090.     IF (@security_check <> 0)
  7091.     BEGIN    
  7092.         EXEC @retcode = dbo.sp_helpdistributor     @rpcsrvname = @dist_rpcname OUTPUT,
  7093.                                                @distribdb   = @distribdb   OUTPUT
  7094.  
  7095.         IF @@error <> 0 OR @retcode <> 0
  7096.             RETURN (1)
  7097.  
  7098.         IF @distribdb is null
  7099.         BEGIN
  7100.             RAISERROR (14071, 16, -1)
  7101.             RETURN (1)
  7102.         END
  7103.  
  7104.         SELECT @proc = RTRIM(@dist_rpcname) + '.' + RTRIM(@distribdb) + '.dbo.sp_MSpublication_access'
  7105.  
  7106.         -- Optimization
  7107.         if is_srvrolemember('sysadmin') = 1
  7108.             select @is_user_admin = 1
  7109.         else
  7110.             insert into #admin_publications EXEC @retcode = @proc
  7111.                  @publisher = @@SERVERNAME,
  7112.                  @operation = 'get_publications',
  7113.                  @login = @login
  7114.  
  7115.         if suser_sid(@agent_login) = suser_sid()
  7116.             select @same_as_user = 1
  7117.         else
  7118.             insert into #agent_publications EXEC @retcode = @proc
  7119.                 @publisher = @@SERVERNAME,
  7120.                 @operation = 'get_publications',
  7121.                 @login = @agent_login
  7122.         
  7123.     END -- IF (@security_check <> 0) 
  7124.  
  7125.     -- commit open tran in case 
  7126.     -- insert into exec failed.
  7127.     while(@@trancount <> 0) commit tran
  7128.  
  7129.     select pub.publisher_db, pub.publication, pub.replication_type, 
  7130.             pub.immediate_sync, pub.allow_pull, pub.allow_anonymous, 
  7131.             pub.enabled_for_internet, pub.repl_freq, pub.immediate_sync_ready, 
  7132.             pub.allow_sync_tran, pub.independent_agent, N'agent_access' = case 
  7133.                 when 
  7134.                     (@same_as_user = 1 or
  7135.                     exists (select * from #agent_publications agent where
  7136.                     agent.publisher_db = pub.publisher_db and
  7137.                     agent.publication = pub.publication))
  7138.                     then convert(bit,1)
  7139.                 else convert(bit,0)
  7140.                 end,
  7141.             pub.thirdparty_flag,
  7142.             pub.vendor_name, pub.publisher, pub.description, pub.distribution_db, 
  7143.             allow_queued_tran, allow_dts, pub.thirdparty_options, pub.queue_type, pub.dynamic_filters
  7144.      from #MSenumpublications pub where exists (select * from #admin_publications admin where
  7145.         pub.publisher_db = admin.publisher_db and
  7146.         pub.publication = admin.publication) or
  7147.         @security_check = 0 or
  7148.         pub.is_db_owner = 1 or
  7149.         @is_user_admin = 1
  7150.      order by pub.publication, pub.publisher_db
  7151.  
  7152.     return (0)
  7153. END
  7154. go
  7155.  
  7156. grant execute on dbo.sp_MSenumallpublications to public
  7157. go 
  7158.  
  7159. raiserror('Creating procedure sp_MSenumtranpublications', 0,1)
  7160. go
  7161.  
  7162. CREATE PROCEDURE sp_MSenumtranpublications (
  7163. @publication sysname
  7164. )
  7165. as
  7166. BEGIN
  7167.     set nocount on
  7168.     select db_name(), name, 1, immediate_sync, allow_pull, allow_anonymous, 
  7169.         enabled_for_internet, repl_freq, immediate_sync_ready, 
  7170.         allow_sync_tran, independent_agent, is_member('db_owner'),
  7171.         0, -- thirdparty
  7172.         'Microsoft SQL Server', @@servername, description,
  7173.         convert(sysname, null),
  7174.         allow_queued_tran,
  7175.         allow_dts
  7176.         ,convert(int,null) -- thirdparty_options
  7177.         ,queue_type
  7178.         ,0 -- dynamic_filters
  7179.         from syspublications pubs
  7180.         where exists (select * from sysextendedarticlesview art where pubs.pubid = art.pubid) 
  7181.             and status <> 0
  7182.             and (pubs.name = @publication or @publication is null)
  7183. END
  7184. go
  7185.  
  7186. raiserror('Creating procedure sp_MSenummergepublications', 0,1)
  7187. go
  7188.  
  7189. CREATE PROCEDURE sp_MSenummergepublications (
  7190. @publication sysname
  7191. )
  7192. as
  7193. BEGIN
  7194.     declare @publisher            sysname
  7195.     declare @publisher_db        sysname
  7196.  
  7197.     select @publisher=@@SERVERNAME
  7198.     select @publisher_db=db_name()
  7199.     
  7200.     set nocount on
  7201.     select db_name(), name, 2, 1, allow_pull, allow_anonymous, enabled_for_internet, 0, snapshot_ready, 0, 1, is_member('db_owner'),
  7202.         0, --thirdparty
  7203.         'Microsoft SQL Server', publisher, description,
  7204.         convert(sysname, null),
  7205.         convert(bit,0), --allow_queued_tran
  7206.         convert(bit,0) --allow_dts
  7207.         ,convert(int, null) -- thirdparty_options
  7208.         ,convert(int, null) -- queue_type
  7209.         ,dynamic_filters 
  7210.         from 
  7211.         sysmergepublications p where status <> 0 
  7212.         and LOWER(publisher)=LOWER(@publisher) 
  7213.         and publisher_db=@publisher_db
  7214.         and (p.name = @publication or @publication is null)
  7215.  
  7216. END
  7217. go
  7218.  
  7219. raiserror('Creating procedure sp_MSenum3rdpartypublications', 0,1)
  7220. go
  7221.  
  7222. CREATE PROCEDURE sp_MSenum3rdpartypublications (
  7223.     @vendor_name sysname,
  7224.     @publication sysname
  7225. )
  7226. as
  7227. BEGIN
  7228.     set nocount on
  7229.     select pubs.publisher_db, publication, 
  7230.         case when publication_type <> 2 then 1
  7231.         else 2
  7232.         end,  --replication_type, 1 tran, 2 merge ; pub type 0 tran 1 snapshot, 2 merge
  7233.         immediate_sync, allow_pull, allow_anonymous, 
  7234.         0,    --enabled_for_internet,
  7235.         case when publication_type = 0 then 0
  7236.         else 1
  7237.         end,  --repl_freq, 
  7238.         1,    --immediate_sync_ready, always return 1 so that UI will not warn
  7239.         0,    -- allow_sync_tran, 
  7240.         independent_agent, 
  7241.         is_member('db_owner'),
  7242.         1, --thirdparty
  7243.         pubs.vendor_name,
  7244.         srv.srvname,
  7245.         pubs.description,
  7246.         db_name(),
  7247.         convert(bit,0), --allow_queued_tran
  7248.         convert(bit,0) --allow_dts
  7249.         ,thirdparty_options
  7250.         ,convert(int, null) -- queue_type
  7251.         ,0 -- dynamic_filters
  7252.         from MSpublications pubs, master..sysservers srv
  7253.         where exists (select * from MSarticles art where 
  7254.                 pubs.publication_id = art.publication_id)  and
  7255.             thirdparty_flag <> 0 and
  7256.             publisher_id = srvid and
  7257.             (@vendor_name <> 'others' and vendor_name = @vendor_name or 
  7258.              @vendor_name  = 'others' and (vendor_name is null or vendor_name = '') or
  7259.              @vendor_name is null ) and
  7260.              (pubs.publication = @publication or @publication is null)
  7261. END
  7262. go
  7263.  
  7264.  
  7265. raiserror('Creating procedure sp_MSenumthirdpartypublicationvendornames', 0,1)
  7266. go
  7267.  
  7268. CREATE PROCEDURE sp_MSenumthirdpartypublicationvendornames(
  7269. @within_db bit = 0
  7270. )
  7271.  
  7272. as
  7273.     set nocount on
  7274.     if @within_db = 0
  7275.     begin
  7276.         declare @dbname         sysname
  7277.         declare @retcode        int
  7278.         declare @distbit        int
  7279.         declare @proc            nvarchar(300)
  7280.  
  7281.         --init
  7282.         SELECT @distbit = 16
  7283.  
  7284.         -- Get publication list
  7285.         create table #pubdbs (publisher_db sysname collate database_default not null)
  7286.  
  7287.         insert into #pubdbs select name from master..sysdatabases where 
  7288.             category & @distbit <> 0 and 
  7289.             has_dbaccess(name) = 1
  7290.  
  7291.         create table #MSenumpublications 
  7292.                 (vendor_name sysname collate database_default not null)
  7293.  
  7294.         declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR select publisher_db from  #pubdbs
  7295.         FOR READ ONLY
  7296.         open hCForEachDb
  7297.         fetch hCForEachDb into @dbname
  7298.         /* Loop for each database */
  7299.         while (@@fetch_status >= 0) 
  7300.         begin
  7301.             select @proc = quotename(@dbname) + 
  7302.                 '.dbo.sp_MSenumthirdpartypublicationvendornames'
  7303.             insert into #MSenumpublications exec @retcode = @proc 1
  7304.             if @@ERROR <> 0 or @retcode <> 0
  7305.                 return (1)
  7306.             fetch hCForEachDb into @dbname
  7307.         end /* while FETCH_SUCCESS */
  7308.     end
  7309.     else
  7310.     begin
  7311.         select distinct vendor_name from MSpublications where thirdparty_flag = 1 and
  7312.             vendor_name is not null and vendor_name <> ''
  7313.     end
  7314.  
  7315.     select distinct vendor_name from #MSenumpublications  order by vendor_name
  7316.  
  7317.     return (0)
  7318. go
  7319.  
  7320. grant execute on dbo.sp_MSenumthirdpartypublicationvendornames to public
  7321. go 
  7322.  
  7323. dump tran master with no_log
  7324. GO
  7325.  
  7326. raiserror('Creating procedure sp_reinitpullsubscription', 0,1)
  7327. go
  7328.  
  7329. CREATE PROCEDURE sp_reinitpullsubscription (
  7330.     @publisher sysname,
  7331.     @publisher_db sysname,
  7332.     @publication sysname = 'all'                       /* publication name */
  7333.     )AS
  7334.  
  7335.     SET NOCOUNT ON
  7336.     
  7337.     declare @subscription_type int    
  7338.     declare @sync_type tinyint
  7339.     /*
  7340.     ** Security Check
  7341.     */
  7342.     
  7343.       declare @retcode     int  
  7344.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  7345.     IF @@ERROR <> 0 or @retcode <> 0
  7346.         RETURN(1)
  7347.  
  7348.     /*
  7349.     ** Initializations.
  7350.     */
  7351.    
  7352.     /*
  7353.     ** Parameter Check: @publisher
  7354.     ** Check to make sure that the publisher is define
  7355.     */
  7356.     IF @publisher IS NULL
  7357.     BEGIN
  7358.         RAISERROR (14043, 16, -1, '@publisher')
  7359.         RETURN (1)
  7360.     END
  7361.  
  7362.     IF @publisher = 'all'
  7363.     BEGIN
  7364.         RAISERROR (14136, 16, -1)
  7365.         RETURN (1)
  7366.     END
  7367.  
  7368.     EXECUTE @retcode = dbo.sp_validname @publisher
  7369.  
  7370.     IF @@ERROR <> 0 OR @retcode <> 0
  7371.        RETURN (1)
  7372.     
  7373.  
  7374.     /*
  7375.     ** Parameter Check: @publisher_db
  7376.     */
  7377.  
  7378.     IF @publisher_db IS NULL
  7379.     BEGIN
  7380.         RAISERROR (14043, 16, -1, '@publisher_db')
  7381.         RETURN (1)
  7382.     END
  7383.  
  7384.     IF @publisher_db = 'all'
  7385.     BEGIN
  7386.         RAISERROR (14136, 16, -1)
  7387.         RETURN (1)
  7388.     END
  7389.  
  7390.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  7391.  
  7392.     IF @@ERROR <> 0 OR @retcode <> 0
  7393.        RETURN (1)
  7394.  
  7395.     /*
  7396.     ** Parameter Check: @publication
  7397.     ** 
  7398.     */
  7399.     IF @publication IS NULL
  7400.     BEGIN
  7401.         RAISERROR (14043, 16, -1, '@publication')
  7402.         RETURN (1)
  7403.     END
  7404.  
  7405.     IF LOWER(@publication) = 'all'
  7406.         select @publication = '%'
  7407.     ELSE
  7408.     BEGIN
  7409.         EXECUTE @retcode = dbo.sp_validname @publication
  7410.  
  7411.         IF @@ERROR <> 0 OR @retcode <> 0
  7412.         RETURN (1)
  7413.     END
  7414.         
  7415.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  7416.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  7417.                       publisher_db  = @publisher_db AND
  7418.                       publication like @publication )
  7419.     BEGIN
  7420.             RAISERROR(14135, 11, -1,  @publisher, @publisher_db, @publication)
  7421.             RETURN(1)
  7422.     END
  7423.         
  7424.     select @sync_type = immediate_sync 
  7425.         from MSreplication_subscriptions
  7426.         WHERE UPPER(publisher) = UPPER(@publisher) AND publisher_db  = @publisher_db AND publication like @publication 
  7427.  
  7428.     IF @sync_type = 0
  7429.     BEGIN
  7430.         raiserror(21059, 16, -1)
  7431.         return (1)
  7432.     END
  7433.         
  7434.     UPDATE MSreplication_subscriptions set 
  7435.         transaction_timestamp = 0x00
  7436.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  7437.                       publisher_db  = @publisher_db AND
  7438.                       publication like @publication 
  7439.     if @@ERROR<>0 
  7440.         RETURN (1)
  7441.  
  7442.     -- Reset the attach state so that the distribution agent will not adjust attach state.
  7443.     if @publication <> '%'
  7444.     begin
  7445.         select @subscription_type = subscription_type from MSreplication_subscriptions
  7446.             WHERE UPPER(publisher) = UPPER(@publisher) AND
  7447.                           publisher_db  = @publisher_db AND
  7448.                           publication = @publication and
  7449.                           -- Don't do this for push
  7450.                           subscription_type <> 0
  7451.         if @subscription_type is not null
  7452.         begin
  7453.             exec @retcode = dbo.sp_MSreset_attach_state 
  7454.                 @publisher = @publisher,
  7455.                 @publisher_db = @publisher_db,
  7456.                 @publication = @publication,
  7457.                 @subscription_type = @subscription_type
  7458.             if @retcode <> 0 or @@error <> 0
  7459.                 return (1)
  7460.         end
  7461.     end
  7462. GO
  7463.  
  7464. grant execute on dbo.sp_reinitpullsubscription to public
  7465. go
  7466.     
  7467. raiserror('Creating procedure sp_addpullsubscription', 0,1)
  7468. go
  7469.  
  7470. CREATE PROCEDURE sp_addpullsubscription (
  7471.     @publisher sysname,
  7472.     @publisher_db sysname,
  7473.     @publication sysname,    /* publication name */
  7474.     @independent_agent nvarchar(5) = 'true',  /* true or false */
  7475.     @subscription_type nvarchar(9) = 'anonymous',     /* subscription_type, pull or anonymous */
  7476.     @description nvarchar(100) = NULL,
  7477.     -- SyncTran
  7478.     @update_mode          nvarchar(15) = 'read only', -- 'sync tran', 'queued tran', 'failover'
  7479.     @immediate_sync        bit = 1
  7480. ) AS
  7481. BEGIN
  7482.  
  7483.     SET NOCOUNT ON
  7484.  
  7485.     /*
  7486.     ** Declarations.
  7487.     */
  7488.  
  7489.     DECLARE @retcode int
  7490.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  7491.     DECLARE @independent_agent_id bit
  7492.     -- SyncTran
  7493.     DECLARE @update_mode_id     tinyint 
  7494.  
  7495.     -- For attach
  7496.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  7497.     begin
  7498.         raiserror(21211, 16, -1)
  7499.         return 1
  7500.     end
  7501.  
  7502.     /* 
  7503.     ** Check if replication components are installed on this server
  7504.     */
  7505.     exec @retcode = dbo.sp_MS_replication_installed
  7506.     if (@retcode <> 1)
  7507.     begin
  7508.         return (1)
  7509.     end
  7510.     
  7511.     /*
  7512.     ** Security Check
  7513.     */
  7514.  
  7515.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  7516.     IF @@ERROR <> 0 or @retcode <> 0
  7517.         RETURN(1)
  7518.  
  7519.     /*
  7520.     ** Initializations.
  7521.     */
  7522.  
  7523.     /*
  7524.     ** Parameter Check: @publisher
  7525.     ** Check to make sure that the publisher is define
  7526.     */
  7527.     IF @publisher IS NULL
  7528.     BEGIN
  7529.         RAISERROR (14043, 16, -1, '@publisher')
  7530.         RETURN (1)
  7531.     END
  7532.  
  7533.     IF @publisher = 'all'
  7534.     BEGIN
  7535.         RAISERROR (14136, 16, -1)
  7536.         RETURN (1)
  7537.     END
  7538.  
  7539.     EXECUTE @retcode = dbo.sp_validname @publisher
  7540.  
  7541.     IF @@ERROR <> 0 OR @retcode <> 0
  7542.        RETURN (1)
  7543.     
  7544.  
  7545.     /*
  7546.     ** Parameter Check: @publisher_db
  7547.     */
  7548.  
  7549.     IF @publisher_db IS NULL
  7550.     BEGIN
  7551.         RAISERROR (14043, 16, -1, '@publisher_db')
  7552.         RETURN (1)
  7553.     END
  7554.  
  7555.     IF @publisher_db = 'all'
  7556.     BEGIN
  7557.         RAISERROR (14136, 16, -1)
  7558.         RETURN (1)
  7559.     END
  7560.  
  7561.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  7562.  
  7563.     IF @@ERROR <> 0 OR @retcode <> 0
  7564.        RETURN (1)
  7565.  
  7566.     /*
  7567.     ** Parameter Check: @publication
  7568.     ** 
  7569.     */
  7570.     IF @publication IS NULL
  7571.     BEGIN
  7572.         RAISERROR (14043, 16, -1, '@publication')
  7573.         RETURN (1)
  7574.     END
  7575.  
  7576.     IF @publication = 'all'
  7577.     BEGIN
  7578.         RAISERROR (14136, 16, -1)
  7579.         RETURN (1)
  7580.     END
  7581.  
  7582.     EXECUTE @retcode = dbo.sp_validname @publication
  7583.  
  7584.     IF @@ERROR <> 0 OR @retcode <> 0
  7585.        RETURN (1)
  7586.  
  7587.     IF @independent_agent IS NULL OR LOWER(@independent_agent collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  7588.         BEGIN
  7589.             RAISERROR (14148, 16, -1, '@independent_agent')
  7590.             RETURN (1)
  7591.         END
  7592.  
  7593.     IF LOWER(@independent_agent collate SQL_Latin1_General_CP1_CS_AS) = 'true' SELECT @independent_agent_id = 1
  7594.     ELSE SELECT @independent_agent_id = 0
  7595.     /*
  7596.     ** Parameter Check:  @subscription_type
  7597.     ** The @status value can be:
  7598.     **
  7599.     **      type_id            type
  7600.     **      ======            ========
  7601.     **             0              push
  7602.     **           1            pull
  7603.     **           2            anonymous
  7604.     **
  7605.     **    Note: @subscription_type = push is only used by distribution agents
  7606.     */
  7607.     
  7608.     IF @subscription_type IS NULL OR LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('push', 'pull','anonymous')
  7609.     BEGIN
  7610.         RAISERROR (20016, 16, -1)
  7611.         RETURN (1)
  7612.     END
  7613.  
  7614.  
  7615.     IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'pull'    
  7616.         SELECT @subscription_type_id = 1
  7617.     ELSE IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'anonymous'  
  7618.         SELECT @subscription_type_id = 2
  7619.     ELSE
  7620.         SELECT @subscription_type_id = 0
  7621.  
  7622.     IF @independent_agent_id = 0 AND @subscription_type_id = 2
  7623.     BEGIN
  7624.         RAISERROR (21026, 16, -1)
  7625.         RETURN (1)
  7626.     END
  7627.  
  7628.     -- SyncTran
  7629.     /*
  7630.     **  Parameter check: @update_mode
  7631.     */
  7632.     /*
  7633.     ** Parameter check: @update_mode
  7634.     */
  7635.     IF (@update_mode IS NULL OR LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) NOT IN 
  7636.         ('read only', 'sync tran', 'queued tran', 'failover'))
  7637.     BEGIN
  7638.         RAISERROR (20502, 16, -1, '@update_mode')
  7639.         RETURN (1)
  7640.     END
  7641.  
  7642.     -- Anonymous subscriptions should not be allowed to 
  7643.     -- subscribe with 'synctran option'    
  7644.     IF LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) in ('sync tran', 'queued tran', 'failover') and
  7645.         @subscription_type_id = 2 
  7646.     begin                      
  7647.            RAISERROR (21057, 16, -1)
  7648.         RETURN (1)
  7649.     end
  7650.  
  7651.     select @update_mode_id = 
  7652.     case
  7653.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'sync tran' then 1
  7654.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'queued tran' then 4
  7655.         when LOWER(@update_mode collate SQL_Latin1_General_CP1_CS_AS) = 'failover' then 5
  7656.         else 0
  7657.     end
  7658.  
  7659.  
  7660.     begin tran
  7661.     save TRAN addpullsubscription
  7662.     
  7663.     /* 
  7664.     ** Check to see if MSreplication_subscriptions and MSsubscription_properties 
  7665.     ** tables exists.
  7666.     ** If not, create it.
  7667.     */
  7668.  
  7669.     exec @retcode = dbo.sp_MScreate_sub_tables
  7670.         @tran_sub_table = 1,
  7671.         @property_table = 1
  7672.     IF @@ERROR <> 0 or @retcode <> 0
  7673.         goto UNDO
  7674.     
  7675.     /*
  7676.     ** Check to make sure that the subscription does not already exist
  7677.     */
  7678.     declare @sub_type int
  7679.     select @sub_type = subscription_type from MSreplication_subscriptions 
  7680.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  7681.                       publisher_db  = @publisher_db AND
  7682.                       publication = @publication
  7683.  
  7684.     -- It is not allowed to subscribe to the same publication twice even with
  7685.     -- differnet subscription type. 
  7686.     -- Raise special error for push
  7687.     if @sub_type is not null
  7688.         if @sub_type = 0
  7689.         begin
  7690.             raiserror (20594, 16, -1)
  7691.             GOTO UNDO            
  7692.         end
  7693.         else
  7694.         begin
  7695.             RAISERROR (14058, 16, -1)
  7696.             GOTO UNDO
  7697.         end
  7698.   
  7699.     /*
  7700.     ** Add the subscription
  7701.     */
  7702.  
  7703.     INSERT MSreplication_subscriptions  (publisher,
  7704.                                     publisher_db,
  7705.                                     publication,
  7706.                                     independent_agent,
  7707.                                     subscription_type,
  7708.                                     distribution_agent,
  7709.                                     description,
  7710.                                     time,
  7711.                                     transaction_timestamp,
  7712.                                     -- SyncTran
  7713.                                     update_mode,
  7714.                                     immediate_sync)
  7715.        VALUES (@publisher,
  7716.                    @publisher_db,
  7717.                    @publication,
  7718.                    @independent_agent_id,    
  7719.                    @subscription_type_id,
  7720.                    NULL,
  7721.                    @description,
  7722.                    getdate(),
  7723.                    0,
  7724.                    -- SyncTran
  7725.                    @update_mode_id,
  7726.                    @immediate_sync
  7727.                    )
  7728.     IF @@ERROR <> 0
  7729.     BEGIN
  7730.        RAISERROR (14057, 16, -1)
  7731.        GOTO UNDO
  7732.     END
  7733.  
  7734.     COMMIT TRAN
  7735.  
  7736.     RETURN (0)
  7737.  
  7738. UNDO:
  7739.     IF @@TRANCOUNT > 0
  7740.     begin
  7741.         ROLLBACK TRAN addpullsubscription
  7742.         COMMIT TRAN   
  7743.     end
  7744.     return 1
  7745. END
  7746. go
  7747.  
  7748. raiserror('Creating procedure sp_MSupdatesharedagentproperties', 0,1)
  7749. go
  7750.  
  7751. CREATE PROCEDURE sp_MSupdatesharedagentproperties (
  7752.     @publisher sysname,
  7753.     @publisher_db sysname,
  7754.     @publication sysname,
  7755.     @property    sysname,
  7756.     @strvalue    nvarchar(256) = NULL,
  7757.     @intvalue    int = NULL,
  7758.     @subscription_type int     
  7759.     )
  7760. AS
  7761.  
  7762.  
  7763.     -- Note publisher/publisher_db/publication uniquely identifies 
  7764.     -- a subscription in MSreplication_subscriptions 
  7765.     CREATE TABLE #subscriptions
  7766.     (
  7767.         publication sysname collate database_default
  7768.     )
  7769.  
  7770.     -- Compute the list of affected subscriptions
  7771.     INSERT INTO #subscriptions SELECT publication FROM
  7772.     MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher)
  7773.     AND publisher_db = @publisher_db AND publication <> @publication
  7774.     AND independent_agent = 0 AND subscription_type = @subscription_type
  7775.  
  7776.     IF (SELECT COUNT(*) FROM #subscriptions) > 0
  7777.     BEGIN 
  7778.  
  7779.         IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor'
  7780.         BEGIN
  7781.             UPDATE MSsubscription_properties SET distributor = @strvalue 
  7782.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7783.                AND publisher_db = @publisher_db
  7784.                AND publication in (SELECT publication FROM #subscriptions)   
  7785.         END
  7786.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_security_mode'
  7787.         BEGIN
  7788.             UPDATE MSsubscription_properties SET distributor_security_mode = @intvalue 
  7789.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7790.                AND publisher_db = @publisher_db
  7791.                AND publication in (SELECT publication FROM #subscriptions)   
  7792.         END
  7793.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_login'
  7794.         BEGIN
  7795.             UPDATE MSsubscription_properties SET distributor_login = @strvalue 
  7796.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7797.                AND publisher_db = @publisher_db
  7798.                AND publication in (SELECT publication FROM #subscriptions)   
  7799.         END
  7800.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_password'
  7801.         BEGIN
  7802.             UPDATE MSsubscription_properties SET distributor_password = @strvalue 
  7803.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7804.                AND publisher_db = @publisher_db
  7805.                AND publication in (SELECT publication FROM #subscriptions)   
  7806.         END
  7807.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'distributor_password'
  7808.         BEGIN
  7809.             UPDATE MSsubscription_properties SET distributor_password = @strvalue 
  7810.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7811.                AND publisher_db = @publisher_db
  7812.                AND publication in (SELECT publication FROM #subscriptions)   
  7813.         END
  7814.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_address'
  7815.         BEGIN
  7816.             UPDATE MSsubscription_properties SET ftp_address = @strvalue 
  7817.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7818.                AND publisher_db = @publisher_db
  7819.                AND publication in (SELECT publication FROM #subscriptions)   
  7820.         END
  7821.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_port'
  7822.         BEGIN
  7823.             UPDATE MSsubscription_properties SET ftp_port = @intvalue 
  7824.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7825.                AND publisher_db = @publisher_db
  7826.                AND publication in (SELECT publication FROM #subscriptions)   
  7827.         END
  7828.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_login'
  7829.         BEGIN
  7830.             UPDATE MSsubscription_properties SET ftp_login = @strvalue 
  7831.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7832.                AND publisher_db = @publisher_db
  7833.                AND publication in (SELECT publication FROM #subscriptions)   
  7834.         END
  7835.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'ftp_password'
  7836.         BEGIN
  7837.             UPDATE MSsubscription_properties SET ftp_password = @strvalue 
  7838.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7839.                AND publisher_db = @publisher_db
  7840.                AND publication in (SELECT publication FROM #subscriptions)   
  7841.         END
  7842.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'alt_snapshot_folder'
  7843.         BEGIN
  7844.             UPDATE MSsubscription_properties SET alt_snapshot_folder = @strvalue 
  7845.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7846.                AND publisher_db = @publisher_db
  7847.                AND publication in (SELECT publication FROM #subscriptions)   
  7848.         END
  7849.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'working_directory'
  7850.         BEGIN
  7851.             UPDATE MSsubscription_properties SET working_directory = @strvalue 
  7852.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7853.                AND publisher_db = @publisher_db
  7854.                AND publication in (SELECT publication FROM #subscriptions)   
  7855.         END
  7856.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'use_ftp'
  7857.         BEGIN
  7858.             UPDATE MSsubscription_properties SET use_ftp = @intvalue 
  7859.              WHERE UPPER(publisher) = UPPER(@publisher)  
  7860.                AND publisher_db = @publisher_db
  7861.                AND publication in (SELECT publication FROM #subscriptions)   
  7862.         END
  7863.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'offload_agent'
  7864.         BEGIN
  7865.             UPDATE MSsubscription_properties SET offload_agent = @intvalue
  7866.              WHERE UPPER(publisher) = UPPER(@publisher)
  7867.                AND publisher_db = @publisher_db
  7868.                AND publication in (SELECT publication FROM #subscriptions)
  7869.         END
  7870.         ELSE IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = N'offload_server'
  7871.         BEGIN
  7872.             UPDATE MSsubscription_properties SET offload_server = @strvalue
  7873.              WHERE UPPER(publisher) = UPPER(@publisher)
  7874.                AND publisher_db = @publisher_db
  7875.                AND publication in (SELECT publication FROM #subscriptions)
  7876.         END
  7877.     END
  7878.  
  7879.     DROP TABLE #subscriptions
  7880.  
  7881.     IF @@ERROR <> 0
  7882.         RETURN 1
  7883.     ELSE
  7884.         RETURN 0
  7885. GO 
  7886.  
  7887. /* Create  sp_replicationdboption */
  7888. raiserror('Creating procedure sp_replicationdboption', 0,1)
  7889. GO
  7890.  
  7891. CREATE PROCEDURE sp_replicationdboption (
  7892.       @dbname    sysname,
  7893.       @optname   sysname,
  7894.       @value     sysname,
  7895.       @ignore_distributor bit = 0,
  7896.       @from_scripting bit = 0
  7897.     ) AS
  7898.  
  7899.     SET NOCOUNT ON
  7900.  
  7901.     /*
  7902.     ** Declarations.
  7903.     */
  7904.     
  7905.     declare @alert_name     sysname
  7906.     declare @alert_id       int
  7907.     declare @command        nvarchar(255)
  7908.     declare @description    nvarchar(500)
  7909.     declare @category_name  sysname
  7910.     declare @agentname      sysname
  7911.     DECLARE @retcode        int
  7912.     DECLARE @optbit         int
  7913.     DECLARE @optbit_value   int /* Desired value with the optbit mask */
  7914.     DECLARE @proc           nvarchar(255)
  7915.         , @category int
  7916.  
  7917.     /*
  7918.     ** Initialization
  7919.     */
  7920.  
  7921.     /*
  7922.     ** Parameter check
  7923.     ** @dbname
  7924.     */
  7925.     SELECT @category = category FROM master.dbo.sysdatabases WHERE
  7926.         name = @dbname collate database_default
  7927.     if @category is null
  7928.     BEGIN
  7929.         RAISERROR(15010, 16, -1, @dbname)
  7930.         RETURN(1)
  7931.     END
  7932.  
  7933.     /*
  7934.     ** Parameter check
  7935.     ** @type
  7936.     */
  7937.     IF @optname is null or LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('publish',
  7938.         'merge publish',
  7939.         'subscribe', -- Used by sp_dboption for backward compatibility only.
  7940.         'sync with backup',
  7941.         'max cmds in tran'
  7942.         )
  7943.     BEGIN
  7944.         RAISERROR(14138,16,-1,@optname)
  7945.         RETURN(1)
  7946.     END
  7947.  
  7948.     /*
  7949.     ** Parameter check
  7950.     ** @value
  7951.     */
  7952.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true','false')
  7953.     BEGIN
  7954.       RAISERROR(14137,16,-1)
  7955.       RETURN(1)
  7956.     END
  7957.  
  7958.     /*
  7959.     ** Security Check
  7960.     */
  7961.     -- This proc is not granted to public. Only other system proc or sysadmin can use this
  7962.     -- sp_dboption will call this and it has its own security check,
  7963.  
  7964.     /*
  7965.     **  If we're in a transaction, disallow this since it might make recovery
  7966.     **  impossible.
  7967.     **
  7968.     */
  7969.     IF @@trancount > 0 
  7970.     BEGIN
  7971.         RAISERROR(15002,16,-1,'sp_replicationdboption')
  7972.         RETURN(1)
  7973.     END
  7974.     
  7975.     IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'publish'
  7976.         BEGIN
  7977.             SELECT @optbit = 1
  7978.             SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSpublishdb'
  7979.         END
  7980.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish'
  7981.         BEGIN
  7982.             SELECT @optbit = 4
  7983.             SELECT @proc = QUOTENAME(@dbname) + '.dbo.sp_MSmergepublishdb'
  7984.         END
  7985.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'subscribe'
  7986.         BEGIN
  7987.             SELECT @optbit = 2
  7988.         END
  7989.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'sync with backup'
  7990.         BEGIN
  7991.             SELECT @optbit = 32
  7992.         END
  7993.     ELSE IF LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'max cmds in tran'
  7994.         BEGIN
  7995.             SELECT @optbit = 64
  7996.         END
  7997.  
  7998.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  7999.         SELECT @optbit_value = @optbit
  8000.     ELSE
  8001.         SELECT @optbit_value = 0
  8002.  
  8003.           
  8004.     /*
  8005.     ** Check if the option is set as required already
  8006.     */
  8007.     if (@category & @optbit) = @optbit_value 
  8008.     BEGIN
  8009.         if @optbit_value = 64 -- setting 'max cmds in tran' to the same, do nothing
  8010.             RETURN (0)
  8011.         if LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8012.             RAISERROR (14035, 10, -1, @optname, @dbname)        
  8013.         else
  8014.             RAISERROR (14037, 10, -1, @optname, @dbname)
  8015.         RETURN (1)
  8016.     END
  8017.  
  8018.     -- If turning on 'sync with backup', make sure 'publish' or 'dist' is turned on already.
  8019.     if  @optbit_value = 32 and (@category & 1 = 0 and @category & 16 = 0)
  8020.     begin
  8021.         raiserror(20019, 16, -1, 'sync with backup')
  8022.         return (1)
  8023.     end
  8024.     if  @optbit_value = 64 and (@category & 16 = 0)
  8025.     begin
  8026.         raiserror(20019, 16, -1, 'max cmds in tran')
  8027.         return (1)
  8028.     end
  8029.  
  8030.     -- We do not allow turning on sync with backup mode at publishing db if the db is
  8031.     -- in simple recovery mode
  8032.     if  @optbit_value = 32 and @category & 1 <> 0 and 
  8033.         databasepropertyex(@dbname, 'recovery') = 'SIMPLE'
  8034.     begin
  8035.         raiserror(20622, 16, -1, 'sync with backup')
  8036.         return (1)
  8037.     end
  8038.     
  8039.     -- If turning off 'publish', turn off 'sync with backup' as well if the database
  8040.     -- is not a distribution database.
  8041.     if @optbit = 1 and @optbit_value = 0 and @category & 32 <> 0 and @category & 16 = 0
  8042.     begin
  8043.         EXEC @retcode =  dbo.sp_replicationdboption   
  8044.             @dbname = @dbname,
  8045.             @optname = 'sync with backup',
  8046.             @value = 'false',
  8047.             @ignore_distributor = @ignore_distributor,
  8048.             @from_scripting = @from_scripting
  8049.         IF @@ERROR <> 0 or @retcode <> 0
  8050.         BEGIN
  8051.             GOTO UNDO
  8052.         END
  8053.     end
  8054.  
  8055.     -- if turning on 'sync with backup' a distribution database, initialize the backup lsns 
  8056.     -- to nulls, this should be done before the category bit is set.
  8057.     declare @backup_proc nvarchar(1000)
  8058.     if @optbit_value = 32 and @category & 16 <> 0
  8059.     begin
  8060.         SELECT @backup_proc = QUOTENAME(@dbname) + 
  8061.             '.dbo.sp_MSrepl_init_backup_lsns'
  8062.         exec @retcode = @backup_proc
  8063.         if @@error <> 0 or @retcode <> 0
  8064.             goto UNDO
  8065.     end
  8066.  
  8067.     /*
  8068.     ** Prepare the required option
  8069.     */
  8070.     if @proc is not null
  8071.     begin
  8072.         EXEC @retcode = @proc @value = @value,
  8073.             @ignore_distributor = @ignore_distributor
  8074.         IF @@ERROR <> 0 or @retcode <> 0
  8075.         BEGIN
  8076.             GOTO UNDO
  8077.         END
  8078.     end
  8079.  
  8080.  
  8081.     /*
  8082.     ** Preparation succeeded. 
  8083.     ** Toggle the category bit in master..sysdatabases
  8084.     */
  8085.     UPDATE master..sysdatabases SET category = category ^ @optbit
  8086.     WHERE name = @dbname
  8087.     IF @@ERROR <> 0 
  8088.     BEGIN
  8089.         GOTO UNDO
  8090.     END
  8091.  
  8092.  
  8093.     declare @num_mergedb int
  8094.     select @num_mergedb = null
  8095.     if lower(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish'
  8096.     begin
  8097.         if lower(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8098.         begin            
  8099.             -- Set the 'startup' option for sp_MScleanupmergepublisher if the
  8100.             -- database is enabled for merge replication.  
  8101.             exec ('use master 
  8102.                    exec dbo.sp_procoption ''sp_MScleanupmergepublisher'', ''startup'', ''true''')
  8103.         end
  8104.         else
  8105.         begin
  8106.             -- Reset the 'startup' option for sp_MScleanupmergepublisher if
  8107.             -- this is the last database that has its 'merge publish' option 
  8108.             -- disabled
  8109.             select @num_mergedb = count(*) from master..sysdatabases 
  8110.              where (category & 4) <> 0
  8111.             if @num_mergedb = 0
  8112.             begin
  8113.                 exec ('use master 
  8114.                        exec dbo.sp_procoption ''sp_MScleanupmergepublisher'', ''startup'', ''false''')
  8115.             end
  8116.         end
  8117.     end
  8118.     
  8119.  
  8120.     -- Get expired subscription cleanup agent name
  8121.     set @agentname = formatmessage(20569)  
  8122.  
  8123.     IF ((LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish') or (LOWER(@optname) = 'publish')) and (LOWER(@value) = 'true')
  8124.     BEGIN
  8125.         IF NOT EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname collate database_default and
  8126.                         UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))
  8127.             BEGIN
  8128.                 SELECT @command =  'EXEC dbo.sp_expired_subscription_cleanup'
  8129.             
  8130.                 set @description = formatmessage(20542)
  8131.     
  8132.                 select @category_name = name FROM msdb.dbo.syscategories where category_id = 17   
  8133.                 
  8134.                 EXECUTE @retcode = msdb.dbo.sp_MSadd_repl_job @agentname,
  8135.                 @subsystem = 'TSQL',
  8136.                 @server = @@SERVERNAME,
  8137.                 @databasename = @dbname,
  8138.                 @description = @description,
  8139.                 @freqtype = 4,        -- daily
  8140.                 @activestarttimeofday=010000,   -- from 01:00:00 am
  8141.                 @command = @command,
  8142.                 @enabled = 1,
  8143.                 @retryattempts = 0,
  8144.                 @loghistcompletionlevel = 0,
  8145.                 @category_name = @category_name
  8146.             
  8147.                 IF @@ERROR <> 0 or @retcode <> 0
  8148.                     BEGIN
  8149.                          return (1)
  8150.                     END
  8151.             END
  8152.  
  8153.         -- Expired subscription cleanup alert            
  8154.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 20
  8155.         set @alert_name = formatmessage(20538)  
  8156.         set @alert_id = 14157 -- corresponding to formatmessage(20538)
  8157.         if not exists (select * from msdb.dbo.sysalerts where message_id = @alert_id)
  8158.         begin
  8159.             exec @retcode = msdb.dbo.sp_add_alert @enabled = 0, @name = @alert_name, @category_name = @category_name, @message_id = 14157
  8160.             if @@error <> 0 or @retcode <> 0
  8161.                 goto UNDO
  8162.         end
  8163.     END
  8164.  
  8165.     IF ((LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'merge publish') or (LOWER(@optname collate SQL_Latin1_General_CP1_CS_AS) = 'publish')) and (LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'false')
  8166.     BEGIN
  8167.             IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE name = @agentname collate database_default and 
  8168.                             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName'))))) 
  8169.                 and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
  8170.                 and (NOT exists (select name from master..sysdatabases where category & 1 =1))
  8171.         BEGIN
  8172.             EXEC @retcode = msdb.dbo.sp_delete_job  @job_name = @agentname
  8173.             IF @@ERROR <> 0 or @retcode <> 0
  8174.                 return (1)            
  8175.         END
  8176.         
  8177.         set @alert_id = 14157 -- cleanup  alert
  8178.         set @alert_name = formatmessage(20569)
  8179.         if exists (select * from msdb.dbo.sysalerts where message_id=@alert_id)
  8180.             and (NOT exists (select name from master..sysdatabases where category & 4 =4 ))
  8181.                 and (NOT exists (select name from master..sysdatabases where category & 1 =1))
  8182.         begin
  8183.             select @alert_name=name from msdb.dbo.sysalerts where message_id=@alert_id
  8184.             exec @retcode = msdb.dbo.sp_delete_alert @alert_name
  8185.             if @@error <> 0 or @retcode <> 0
  8186.                 return (1)            
  8187.         end
  8188.     END
  8189.     
  8190.     /*
  8191.     **  ??? 
  8192.     ** CHECKPOINT the database that was changed. Make the change
  8193.     ** effective immediatly
  8194.     */
  8195.     CHECKPOINT
  8196.     IF @@ERROR <> 0 
  8197.     BEGIN
  8198.         RETURN(1)
  8199.     END
  8200.  
  8201.     RETURN(0)
  8202.  
  8203. UNDO:
  8204.     -- Create system table is not allowed in a multi-statement transactions.
  8205.     -- Drop the tables here
  8206.     IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  8207.         EXEC dbo.sp_replicationdboption 
  8208.           @dbname    = @dbname,
  8209.           @optname   = @optname,
  8210.           @value     = 'false',
  8211.           @ignore_distributor = @ignore_distributor
  8212.  
  8213.     return(1)   
  8214. GO
  8215.  
  8216. raiserror('Creating procedure sp_MSfixupdistributorinfo', 0,1)
  8217. go
  8218.  
  8219. CREATE PROCEDURE sp_MSfixupdistributorinfo (
  8220.     @publisher sysname,
  8221.     @publisher_db sysname,
  8222.     @publication sysname,
  8223.     @distributor sysname,
  8224.     @subscription_type int
  8225.     )
  8226. AS
  8227.     DECLARE @local_distributor sysname
  8228.     DECLARE @retcode INT
  8229.  
  8230.     -- If @distributor = @publisher
  8231.     -- we just assume that these values are unspecified 
  8232.     -- and so we inherit these values from other shared subscriptions
  8233.     -- if possible
  8234.     IF @distributor = @publisher
  8235.     BEGIN
  8236.         SELECT TOP 1 @local_distributor = sp.distributor
  8237.           FROM MSsubscription_properties sp
  8238.           JOIN MSreplication_subscriptions rs  
  8239.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8240.            AND sp.publisher_db = rs.publisher_db
  8241.            AND rs.subscription_type = @subscription_type
  8242.            AND rs.independent_agent = 0
  8243.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8244.            AND sp.publisher_db = @publisher_db
  8245.            AND sp.publication <> @publication
  8246.                       
  8247.         IF @@ROWCOUNT > 0
  8248.         BEGIN
  8249.            -- Inherit the values from other shared subscriptions
  8250.            UPDATE MSsubscription_properties SET 
  8251.             distributor = @local_distributor
  8252.             WHERE UPPER(publisher) = UPPER(@publisher)
  8253.               AND publisher_db = @publisher_db
  8254.               AND publication = @publication
  8255.         END  
  8256.     END
  8257.     ELSE
  8258.     BEGIN
  8259.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8260.            @publisher = @publisher,
  8261.            @publisher_db = @publisher_db,
  8262.            @publication = @publication,
  8263.            @property = N'distributor',
  8264.            @strvalue = @distributor,
  8265.            @subscription_type = @subscription_type
  8266.         
  8267.         IF @retcode <> 0 OR @@ERROR <> 0
  8268.             GOTO FixupFailure
  8269.                                     
  8270.     END
  8271.  
  8272.     RETURN 0
  8273.  
  8274. FixupFailure:
  8275.     RETURN 1
  8276.  
  8277. GO
  8278.  
  8279. raiserror('Creating procedure sp_MSfixupdistributorsecurity', 0,1)
  8280. go
  8281.  
  8282. CREATE PROCEDURE sp_MSfixupdistributorsecurity (
  8283.     @publisher sysname,
  8284.     @publisher_db sysname,
  8285.     @publication sysname,
  8286.     @distributor_security_mode int, -- default 0 -- standard
  8287.     @distributor_login sysname, -- default 'sa'
  8288.     @distributor_password nvarchar(524), -- default null
  8289.     @subscription_type int
  8290.     )
  8291. AS
  8292.     DECLARE @local_distributor_security_mode int
  8293.     DECLARE @local_distributor_login sysname 
  8294.     DECLARE @local_distributor_password nvarchar(524) 
  8295.     DECLARE @retcode INT
  8296.  
  8297.  
  8298.     IF @distributor_security_mode = 0 AND @distributor_login = 'sa' 
  8299.        AND (@distributor_password IS NULL OR 
  8300.             @distributor_password = N'') 
  8301.     BEGIN
  8302.         -- Parameters are unspecifed, try to inherit values from
  8303.         -- shared susbcriptions
  8304.         SELECT TOP 1 @local_distributor_security_mode = distributor_security_mode,
  8305.                      @local_distributor_login = distributor_login,
  8306.                      @local_distributor_password = distributor_password
  8307.                      FROM MSsubscription_properties sp
  8308.                      JOIN MSreplication_subscriptions rs  
  8309.                        ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8310.                       AND sp.publisher_db = rs.publisher_db
  8311.                       AND rs.subscription_type = @subscription_type
  8312.                       AND rs.independent_agent = 0
  8313.                     WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8314.                       AND sp.publisher_db = @publisher_db
  8315.                       AND sp.publication <> @publication
  8316.         IF @@ROWCOUNT > 0              
  8317.         BEGIN
  8318.            -- Inherit the values from other shared subscriptions
  8319.            UPDATE MSsubscription_properties SET 
  8320.            distributor_security_mode = @local_distributor_security_mode,
  8321.            distributor_login = @local_distributor_login,
  8322.            distributor_password = @local_distributor_password
  8323.             WHERE UPPER(publisher) = UPPER(@publisher)
  8324.               AND publisher_db = @publisher_db
  8325.               AND publication = @publication
  8326.         END  
  8327.     END
  8328.     ELSE
  8329.     BEGIN
  8330.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8331.            @publisher = @publisher,
  8332.            @publisher_db = @publisher_db,
  8333.            @publication = @publication,
  8334.            @property = N'distributor_security_mode',
  8335.            @intvalue = @distributor_security_mode,
  8336.            @subscription_type = @subscription_type
  8337.         
  8338.         IF @retcode <> 0 OR @@ERROR <> 0
  8339.             GOTO FixupFailure
  8340.                                     
  8341.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8342.            @publisher = @publisher,
  8343.            @publisher_db = @publisher_db,
  8344.            @publication = @publication,
  8345.            @property = N'distributor_login',
  8346.            @strvalue = @distributor_login,
  8347.            @subscription_type = @subscription_type
  8348.         
  8349.         IF @retcode <> 0 OR @@ERROR <> 0
  8350.             GOTO FixupFailure
  8351.  
  8352.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8353.            @publisher = @publisher,
  8354.            @publisher_db = @publisher_db,
  8355.            @publication = @publication,
  8356.            @property = N'distributor_password',
  8357.            @strvalue = @distributor_password,
  8358.            @subscription_type = @subscription_type
  8359.         
  8360.         IF @retcode <> 0 OR @@ERROR <> 0
  8361.             GOTO FixupFailure
  8362.     END
  8363.  
  8364.     RETURN 0
  8365.  
  8366. FixupFailure:
  8367.     RETURN 1
  8368.  
  8369. GO
  8370.  
  8371. raiserror('Creating procedure sp_MSfixupftpinfo', 0,1)
  8372. go
  8373.  
  8374. CREATE PROCEDURE sp_MSfixupftpinfo (
  8375.     @publisher sysname,
  8376.     @publisher_db sysname,
  8377.     @publication sysname,
  8378.     @ftp_address sysname,         -- default null
  8379.     @ftp_port int,                -- default null
  8380.     @ftp_login sysname,           -- default null
  8381.     @ftp_password nvarchar(524),  -- default null
  8382.     @subscription_type int,
  8383.     @force_null bit 
  8384.     )
  8385. AS
  8386.     DECLARE @local_ftp_address sysname
  8387.     DECLARE @local_ftp_port sysname 
  8388.     DECLARE @local_ftp_login sysname
  8389.     DECLARE @local_ftp_password nvarchar(524)
  8390.     DECLARE @retcode INT
  8391.  
  8392.     IF @ftp_address IS NULL AND @ftp_port IS NULL AND
  8393.        @ftp_login IS NULL AND @ftp_password IS NULL AND
  8394.        @force_null = 0
  8395.     BEGIN
  8396.         -- Parameters are unspecifed, try to inherit values from
  8397.         -- shared susbcriptions
  8398.         SELECT TOP 1 @local_ftp_address = ftp_address,
  8399.                      @local_ftp_port = ftp_port,
  8400.                      @local_ftp_login = ftp_login,
  8401.                      @local_ftp_password = ftp_password
  8402.           FROM MSsubscription_properties sp
  8403.           JOIN MSreplication_subscriptions rs  
  8404.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8405.            AND sp.publisher_db = rs.publisher_db
  8406.            AND rs.subscription_type = @subscription_type
  8407.            AND rs.independent_agent = 0
  8408.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8409.            AND sp.publisher_db = @publisher_db
  8410.            AND sp.publication <> @publication
  8411.         IF @@ROWCOUNT > 0              
  8412.         BEGIN
  8413.            -- Inherit the values from other shared subscriptions
  8414.            UPDATE MSsubscription_properties SET 
  8415.             ftp_address = @local_ftp_address,
  8416.             ftp_port = @local_ftp_port,
  8417.             ftp_login = @local_ftp_login,
  8418.             ftp_password = @local_ftp_password
  8419.             WHERE UPPER(publisher) = UPPER(@publisher)
  8420.               AND publisher_db = @publisher_db
  8421.               AND publication = @publication
  8422.         END  
  8423.     END
  8424.     ELSE
  8425.     BEGIN
  8426.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8427.            @publisher = @publisher,
  8428.            @publisher_db = @publisher_db,
  8429.            @publication = @publication,
  8430.            @property = N'ftp_address',
  8431.            @strvalue = @ftp_address,
  8432.            @subscription_type = @subscription_type
  8433.         
  8434.         IF @retcode <> 0 OR @@ERROR <> 0
  8435.             GOTO FixupFailure
  8436.                                     
  8437.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8438.            @publisher = @publisher,
  8439.            @publisher_db = @publisher_db,
  8440.            @publication = @publication,
  8441.            @property = N'ftp_port',
  8442.            @intvalue = @ftp_port,
  8443.            @subscription_type = @subscription_type
  8444.         
  8445.         IF @retcode <> 0 OR @@ERROR <> 0
  8446.             GOTO FixupFailure
  8447.  
  8448.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8449.            @publisher = @publisher,
  8450.            @publisher_db = @publisher_db,
  8451.            @publication = @publication,
  8452.            @property = N'ftp_login',
  8453.            @strvalue = @ftp_login,
  8454.            @subscription_type = @subscription_type
  8455.         
  8456.         IF @retcode <> 0 OR @@ERROR <> 0
  8457.             GOTO FixupFailure
  8458.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8459.            @publisher = @publisher,
  8460.            @publisher_db = @publisher_db,
  8461.            @publication = @publication,
  8462.            @property = N'ftp_password',
  8463.            @strvalue = @ftp_password,
  8464.            @subscription_type = @subscription_type
  8465.         
  8466.         IF @retcode <> 0 OR @@ERROR <> 0
  8467.             GOTO FixupFailure
  8468.     END
  8469.  
  8470.     RETURN 0
  8471.  
  8472. FixupFailure:
  8473.     RETURN 1
  8474.  
  8475. GO
  8476.  
  8477. raiserror('Creating procedure sp_MSfixupaltsnapshotfolder', 0,1)
  8478. go
  8479.  
  8480. CREATE PROCEDURE sp_MSfixupaltsnapshotfolder (
  8481.     @publisher sysname,
  8482.     @publisher_db sysname,
  8483.     @publication sysname,
  8484.     @alt_snapshot_folder nvarchar(255), -- default null
  8485.     @subscription_type int,
  8486.     @force_null bit 
  8487.     )
  8488. AS
  8489.  
  8490.     DECLARE @local_alt_snapshot_folder sysname 
  8491.     DECLARE @retcode INT
  8492.  
  8493.     IF @alt_snapshot_folder IS NULL AND @force_null = 0
  8494.     BEGIN
  8495.         -- Parameter is unspecifed, try to inherit value from
  8496.         -- shared susbcriptions
  8497.         SELECT TOP 1 @local_alt_snapshot_folder = alt_snapshot_folder
  8498.           FROM MSsubscription_properties sp
  8499.           JOIN MSreplication_subscriptions rs  
  8500.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8501.            AND sp.publisher_db = rs.publisher_db
  8502.            AND rs.subscription_type = @subscription_type
  8503.            AND rs.independent_agent = 0
  8504.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8505.            AND sp.publisher_db = @publisher_db
  8506.            AND sp.publication <> @publication
  8507.         IF @@ROWCOUNT > 0           
  8508.         BEGIN
  8509.            -- Inherit the values from other shared subscriptions
  8510.            UPDATE MSsubscription_properties SET 
  8511.             alt_snapshot_folder = @local_alt_snapshot_folder
  8512.             WHERE UPPER(publisher) = UPPER(@publisher)
  8513.               AND publisher_db = @publisher_db
  8514.               AND publication = @publication
  8515.         END  
  8516.     END
  8517.     ELSE
  8518.     BEGIN
  8519.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8520.            @publisher = @publisher,
  8521.            @publisher_db = @publisher_db,
  8522.            @publication = @publication,
  8523.            @property = N'alt_snapshot_folder',
  8524.            @strvalue = @alt_snapshot_folder,
  8525.            @subscription_type = @subscription_type
  8526.         
  8527.         IF @retcode <> 0 OR @@ERROR <> 0
  8528.             GOTO FixupFailure                                    
  8529.     END
  8530.  
  8531.     RETURN 0
  8532.  
  8533. FixupFailure:
  8534.     RETURN 1
  8535.  
  8536. GO
  8537.  
  8538. raiserror('Creating procedure sp_MSfixupworkingdirectory', 0,1)
  8539. go
  8540.  
  8541. CREATE PROCEDURE sp_MSfixupworkingdirectory (
  8542.     @publisher sysname,
  8543.     @publisher_db sysname,
  8544.     @publication sysname,
  8545.     @working_directory nvarchar(255), -- default null
  8546.     @subscription_type int
  8547.     )
  8548. AS
  8549.  
  8550.     DECLARE @local_working_directory sysname 
  8551.     DECLARE @retcode INT
  8552.  
  8553.     IF @working_directory IS NULL
  8554.     BEGIN
  8555.         -- Parameter is unspecifed, try to inherit value from
  8556.         -- shared susbcriptions
  8557.         SELECT TOP 1 @local_working_directory = working_directory
  8558.           FROM MSsubscription_properties sp
  8559.           JOIN MSreplication_subscriptions rs  
  8560.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8561.            AND sp.publisher_db = rs.publisher_db
  8562.            AND rs.subscription_type = @subscription_type
  8563.            AND rs.independent_agent = 0
  8564.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8565.            AND sp.publisher_db = @publisher_db
  8566.            AND sp.publication <> @publication
  8567.         IF @@ROWCOUNT > 0           
  8568.         BEGIN
  8569.            -- Inherit the values from other shared subscriptions
  8570.            UPDATE MSsubscription_properties SET 
  8571.             working_directory = @local_working_directory
  8572.             WHERE UPPER(publisher) = UPPER(@publisher)
  8573.               AND publisher_db = @publisher_db
  8574.               AND publication = @publication
  8575.         END  
  8576.     END
  8577.     ELSE
  8578.     BEGIN
  8579.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8580.            @publisher = @publisher,
  8581.            @publisher_db = @publisher_db,
  8582.            @publication = @publication,
  8583.            @property = N'working_directory',
  8584.            @strvalue = @working_directory,
  8585.            @subscription_type = @subscription_type
  8586.         
  8587.         IF @retcode <> 0 OR @@ERROR <> 0
  8588.             GOTO FixupFailure                                    
  8589.     END
  8590.  
  8591.     RETURN 0
  8592.  
  8593. FixupFailure:
  8594.     RETURN 1
  8595.  
  8596. GO
  8597.  
  8598. raiserror('Creating procedure sp_MSfixupuseftp', 0,1)
  8599. go
  8600.  
  8601. CREATE PROCEDURE sp_MSfixupuseftp (
  8602.     @publisher sysname,
  8603.     @publisher_db sysname,
  8604.     @publication sysname,
  8605.     @use_ftp bit, -- default null
  8606.     @subscription_type int,
  8607.     @force_zero bit
  8608.     )
  8609. AS
  8610.  
  8611.     DECLARE @local_use_ftp bit
  8612.     DECLARE @retcode INT
  8613.  
  8614.     IF @use_ftp = 0 AND @force_zero = 0
  8615.     BEGIN
  8616.         -- Parameter is unspecifed, try to inherit value from
  8617.         -- shared susbcriptions
  8618.         SELECT TOP 1 @local_use_ftp = use_ftp
  8619.           FROM MSsubscription_properties sp
  8620.           JOIN MSreplication_subscriptions rs  
  8621.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8622.            AND sp.publisher_db = rs.publisher_db
  8623.            AND rs.subscription_type = @subscription_type
  8624.            AND rs.independent_agent = 0
  8625.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8626.            AND sp.publisher_db = @publisher_db
  8627.            AND sp.publication <> @publication
  8628.         IF @@ROWCOUNT > 0           
  8629.         BEGIN
  8630.            -- Inherit the values from other shared subscriptions
  8631.            UPDATE MSsubscription_properties SET 
  8632.             use_ftp = @local_use_ftp
  8633.             WHERE UPPER(publisher) = UPPER(@publisher)
  8634.               AND publisher_db = @publisher_db
  8635.               AND publication = @publication
  8636.         END  
  8637.     END
  8638.     ELSE
  8639.     BEGIN
  8640.         EXEC @retcode = sp_MSupdatesharedagentproperties 
  8641.            @publisher = @publisher,
  8642.            @publisher_db = @publisher_db,
  8643.            @publication = @publication,
  8644.            @property = N'use_ftp',
  8645.            @intvalue = @use_ftp,
  8646.            @subscription_type = @subscription_type
  8647.         
  8648.         IF @retcode <> 0 OR @@ERROR <> 0
  8649.             GOTO FixupFailure                                    
  8650.     END
  8651.  
  8652.     RETURN 0
  8653.  
  8654. FixupFailure:
  8655.     RETURN 1
  8656.  
  8657. GO
  8658.  
  8659. raiserror('Creating procedure sp_MSfixup_offload_agent_info', 0,1)
  8660. go
  8661.  
  8662. CREATE PROCEDURE sp_MSfixupagentoffloadinfo (
  8663.     @publisher sysname,
  8664.     @publisher_db sysname,
  8665.     @publication sysname,
  8666.     @distributor sysname,
  8667.     @offload_agent bit, -- default 0
  8668.     @offload_server sysname, -- default null
  8669.     @subscription_type int
  8670.     )
  8671. AS
  8672.     DECLARE @local_offload_agent bit
  8673.     DECLARE @local_offload_server sysname
  8674.     DECLARE @retcode INT
  8675.  
  8676.     IF @offload_agent = 0 AND 
  8677.         @offload_server is null
  8678.     BEGIN
  8679.         -- Parameters are assumed to be be unspecified, try to inherit values 
  8680.         -- from shared subscriptions
  8681.         SELECT TOP 1 @local_offload_agent = offload_agent,
  8682.                      @local_offload_server = offload_server
  8683.           FROM MSsubscription_properties sp
  8684.           JOIN MSreplication_subscriptions rs
  8685.             ON UPPER(sp.publisher) = UPPER(rs.publisher)
  8686.            AND sp.publisher_db = rs.publisher_db
  8687.            AND rs.subscription_type = @subscription_type
  8688.            AND rs.independent_agent = 0
  8689.          WHERE UPPER(sp.publisher) = UPPER(@publisher)
  8690.            AND sp.publisher_db = @publisher_db
  8691.            AND sp.publication <> @publication
  8692.         IF @@ROWCOUNT > 0
  8693.         BEGIN
  8694.             -- Inherit the values from other shared subscriptions
  8695.             UPDATE MSsubscription_properties SET
  8696.              offload_agent = @local_offload_agent,
  8697.              offload_server = @local_offload_server
  8698.             WHERE UPPER(publisher) = UPPER(@publisher)
  8699.               AND publisher_db = @publisher_db
  8700.               AND publication = @publication
  8701.         END
  8702.     END
  8703.     ELSE
  8704.     BEGIN
  8705.         EXEC @retcode = sp_MSupdatesharedagentproperties
  8706.             @publisher = @publisher,
  8707.             @publisher_db = @publisher_db,
  8708.             @publication = @publication,
  8709.             @property = N'offload_agent',
  8710.             @intvalue = @offload_agent,
  8711.             @subscription_type = @subscription_type
  8712.  
  8713.         IF @retcode <> 0 OR @@ERROR <> 0
  8714.             GOTO FixupFailure
  8715.         
  8716.         EXEC @retcode = sp_MSupdatesharedagentproperties
  8717.             @publisher = @publisher,
  8718.             @publisher_db = @publisher_db,
  8719.             @publication = @publication,
  8720.             @property = N'offload_server',
  8721.             @strvalue = @offload_server,
  8722.             @subscription_type = @subscription_type
  8723.     END
  8724.              
  8725.     RETURN 0
  8726.  
  8727. FixupFailure:
  8728.     RETURN 1
  8729.  
  8730. GO
  8731.  
  8732. raiserror('Creating procedure sp_MSfixupsharedagentproperties', 0,1)
  8733. go
  8734.  
  8735. CREATE PROCEDURE sp_MSfixupsharedagentproperties (
  8736.     @publisher sysname,
  8737.     @publisher_db sysname,
  8738.     @publication sysname,         /* publication name */
  8739.     @distributor sysname,       -- default @publisher
  8740.     @distributor_security_mode int, -- default 0 -- standard
  8741.     @distributor_login sysname, -- default 'sa'
  8742.     @distributor_password nvarchar(524), -- default null
  8743.     @ftp_address sysname,       -- default null
  8744.     @ftp_port int,              -- default null
  8745.     @ftp_login sysname,         -- default null
  8746.     @ftp_password nvarchar(524),      -- default null
  8747.     @alt_snapshot_folder nvarchar(255), -- default null
  8748.     @working_directory   nvarchar(255), -- default null
  8749.     @use_ftp bit,               -- default 0
  8750.     @offload_agent bit,         -- default 0
  8751.     @offload_server sysname     -- default @distributor
  8752.     )
  8753. AS
  8754.     DECLARE @subscription_type int
  8755.     DECLARE @retcode int
  8756.     DECLARE @force_ftp_null bit
  8757.     DECLARE @force_alt_snapshot_folder_null bit
  8758.  
  8759.     IF @alt_snapshot_folder IS NOT NULL AND @alt_snapshot_folder <> N''
  8760.         SELECT @force_ftp_null = 1 
  8761.     ELSE
  8762.         SELECT @force_ftp_null = 0 
  8763.  
  8764.     IF (@use_ftp = 1)  OR (@ftp_address IS NOT NULL AND @ftp_address <> N'')
  8765.         SELECT @force_alt_snapshot_folder_null = 1 
  8766.     ELSE
  8767.         SELECT @force_alt_snapshot_folder_null = 0 
  8768.         
  8769.     SELECT @subscription_type = subscription_type
  8770.       FROM MSreplication_subscriptions 
  8771.      WHERE UPPER(publisher) = UPPER(@publisher)
  8772.        AND publisher_db = @publisher_db
  8773.        AND publication = @publication
  8774.     -- No need to fix up the publisher security properties 
  8775.     -- because they are defined on a per subscription 
  8776.     -- basis for SyncTran
  8777.  
  8778.     EXEC @retcode = sp_MSfixupdistributorinfo
  8779.         @publisher = @publisher,
  8780.         @publisher_db = @publisher_db,
  8781.         @publication = @publication,
  8782.         @distributor = @distributor,
  8783.         @subscription_type = @subscription_type
  8784.  
  8785.     IF @@ERROR <> 0 OR @retcode <> 0
  8786.         GOTO FixupFailure
  8787.  
  8788.     EXEC @retcode = sp_MSfixupdistributorsecurity 
  8789.         @publisher = @publisher,
  8790.         @publisher_db = @publisher_db,
  8791.         @publication = @publication,
  8792.         @distributor_login = @distributor_login,
  8793.         @distributor_password = @distributor_password,
  8794.         @distributor_security_mode = @distributor_security_mode,                            
  8795.         @subscription_type = @subscription_type
  8796.  
  8797.     IF @@ERROR <> 0 OR @retcode <> 0
  8798.         GOTO FixupFailure
  8799.  
  8800. /* Ignore ftp_address, ftp_port, ftp_login, ftp_password on post 7.0 server
  8801.     EXEC @retcode = sp_MSfixupftpinfo
  8802.         @publisher = @publisher,
  8803.         @publisher_db = @publisher_db,
  8804.         @publication = @publication,
  8805.         @ftp_address = @ftp_address,
  8806.         @ftp_port = @ftp_port,
  8807.         @ftp_login = @ftp_login,
  8808.         @ftp_password = @ftp_password,
  8809.         @subscription_type = @subscription_type,
  8810.         @force_null = @force_ftp_null
  8811.  
  8812.     IF @@ERROR <> 0 OR @retcode <> 0
  8813.         GOTO FixupFailure
  8814. */
  8815.     EXEC @retcode = sp_MSfixupaltsnapshotfolder
  8816.         @publisher = @publisher,
  8817.         @publisher_db = @publisher_db,
  8818.         @publication = @publication,
  8819.         @alt_snapshot_folder = @alt_snapshot_folder,
  8820.         @subscription_type = @subscription_type,
  8821.         @force_null = @force_alt_snapshot_folder_null
  8822.  
  8823.     IF @@ERROR <> 0 OR @retcode <> 0
  8824.         GOTO FixupFailure
  8825.  
  8826.     EXEC @retcode = sp_MSfixupworkingdirectory
  8827.         @publisher = @publisher,
  8828.         @publisher_db = @publisher_db,
  8829.         @publication = @publication,
  8830.         @working_directory = @working_directory,
  8831.         @subscription_type = @subscription_type
  8832.  
  8833.     IF @@ERROR <> 0 OR @retcode <> 0
  8834.         GOTO FixupFailure
  8835.  
  8836.     EXEC @retcode = sp_MSfixupuseftp
  8837.         @publisher = @publisher,
  8838.         @publisher_db = @publisher_db,
  8839.         @publication = @publication,
  8840.         @use_ftp = @use_ftp,
  8841.         @subscription_type = @subscription_type,
  8842.         @force_zero = @force_ftp_null
  8843.  
  8844.     IF @@ERROR <> 0 OR @retcode <> 0
  8845.         GOTO FixupFailure
  8846.  
  8847.     EXEC @retcode = sp_MSfixupagentoffloadinfo
  8848.         @publisher = @publisher,
  8849.         @publisher_db = @publisher_db,
  8850.         @publication = @publication,
  8851.         @distributor = @distributor,
  8852.         @offload_agent = @offload_agent,
  8853.         @offload_server = @offload_server,
  8854.         @subscription_type = @subscription_type
  8855.  
  8856.     IF @@ERROR <> 0 OR @retcode <> 0
  8857.         GOTO FixupFailure
  8858.  
  8859.     RETURN 0
  8860.  
  8861. FixupFailure:
  8862.  
  8863.     RETURN 1
  8864.  
  8865. GO
  8866.  
  8867. raiserror('Creating procedure sp_addpullsubscription_agent', 0,1)
  8868. go
  8869.  
  8870. CREATE PROCEDURE sp_addpullsubscription_agent (
  8871.     @publisher sysname,
  8872.     @publisher_db sysname,
  8873.     @publication sysname,         /* publication name */
  8874.     @subscriber sysname = NULL,
  8875.     @subscriber_db sysname = NULL,
  8876.     @subscriber_security_mode       int = NULL,                     /* 0 standard; 1 integrated */
  8877.     @subscriber_login               sysname = NULL,
  8878.     @subscriber_password            sysname = NULL,
  8879.     @distributor sysname = @publisher,
  8880.     @distribution_db sysname = NULL,
  8881.     @distributor_security_mode int = 0,
  8882.     @distributor_login sysname = 'sa',
  8883.     @distributor_password sysname = NULL,
  8884.     @optional_command_line nvarchar(4000) = '',
  8885.     @frequency_type  int = 2 ,  /* 2== OnDemand */
  8886.     @frequency_interval int = 1, 
  8887.     @frequency_relative_interval int = 1, 
  8888.     @frequency_recurrence_factor int = 1, 
  8889.     @frequency_subday int = 1, 
  8890.     @frequency_subday_interval int = 1 ,
  8891.     @active_start_time_of_day int = 0, 
  8892.     @active_end_time_of_day int = 0,         
  8893.     @active_start_date int = 0, 
  8894.     @active_end_date int =0,
  8895.     @distribution_jobid binary(16) = NULL OUTPUT,
  8896.     @encrypted_distributor_password bit = 0,
  8897.     @enabled_for_syncmgr nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  8898.     @ftp_address sysname = NULL,
  8899.     @ftp_port int = NULL,
  8900.     @ftp_login sysname = NULL,
  8901.     @ftp_password sysname = NULL,
  8902.     @alt_snapshot_folder  nvarchar(255) = NULL,
  8903.     @working_directory    nvarchar(255) = NULL,
  8904.     @use_ftp              nvarchar(5) = 'false',
  8905.     @publication_type     tinyint = 0,-- 0 - Transactional, 1 - Snapshot, 2 - Merge
  8906.     @dts_package_name sysname  = NULL,  /* value will be sent and validated at distributor */                                  
  8907.     @dts_package_password  sysname = NULL,
  8908.     @dts_package_location nvarchar(12) = N'subscriber',
  8909.     @reserved nvarchar(100) = N'', -- Not default to null because null problems in conditional expressions.
  8910.     @offloadagent          nvarchar(5) = 'false',
  8911.     @offloadserver         sysname = NULL,
  8912.     @job_name              sysname = NULL
  8913.     ) AS
  8914.  
  8915.     SET NOCOUNT ON
  8916.  
  8917.     /*
  8918.     ** Declarations.
  8919.     */
  8920.  
  8921.     DECLARE @command nvarchar(4000)
  8922.     DECLARE @retcode int
  8923.     DECLARE @subscription_type_id int   /* 1 = pull, 2 = anonymous */
  8924.     DECLARE @independent_agent_id bit
  8925.     DECLARE @distribution_agent nvarchar(100) 
  8926.     DECLARE @category_name sysname
  8927.     DECLARE @platform_nt binary
  8928.     DECLARE @subscriber_enc_password nvarchar(524)
  8929.     DECLARE @distributor_enc_password   nvarchar(524)
  8930.     DECLARE @use_ftp_bit bit
  8931.     DECLARE @offload_agent_bit bit
  8932.     
  8933.     select @platform_nt = 0x1
  8934.  
  8935.     /*
  8936.     ** Security Check
  8937.     */
  8938.  
  8939.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  8940.     IF @@ERROR <> 0 or @retcode <> 0
  8941.         RETURN(1)
  8942.  
  8943.     /*
  8944.     ** Initializations.
  8945.     */
  8946.  
  8947.     -- Set null @optional_command_line to empty string to avoid string concat problem
  8948.     if @optional_command_line is null
  8949.         set @optional_command_line = ''
  8950.     else
  8951.         set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  8952.  
  8953.     IF @distributor_password = N''
  8954.         select @distributor_password = NULL
  8955.  
  8956.     IF @ftp_password = N''
  8957.         select @ftp_password = NULL
  8958.  
  8959.     IF @dts_package_password = N''
  8960.         select @dts_package_password = NULL
  8961.  
  8962.     /*
  8963.     ** Parameter Check: @publisher
  8964.     ** Check to make sure that the publisher is define
  8965.     */
  8966.     IF @publisher IS NULL
  8967.     BEGIN
  8968.         RAISERROR (14043, 16, -1, '@publisher')
  8969.         RETURN (1)
  8970.     END
  8971.  
  8972.     EXECUTE @retcode = dbo.sp_validname @publisher
  8973.  
  8974.     IF @@ERROR <> 0 OR @retcode <> 0
  8975.        RETURN (1)
  8976.     
  8977.  
  8978.     /*
  8979.     ** Parameter Check: @publisher_db
  8980.     */
  8981.  
  8982.     IF @publisher_db IS NULL
  8983.     BEGIN
  8984.         RAISERROR (14043, 16, -1, '@publisher_db')
  8985.         RETURN (1)
  8986.     END
  8987.  
  8988.     EXECUTE @retcode = dbo.sp_validname @publisher_db
  8989.  
  8990.     IF @@ERROR <> 0 OR @retcode <> 0
  8991.        RETURN (1)
  8992.  
  8993.     /*
  8994.     ** Parameter Check: @publication
  8995.     ** 
  8996.     */
  8997.     IF @publication IS NULL
  8998.     BEGIN
  8999.         RAISERROR (14043, 16, -1, '@publication')
  9000.         RETURN (1)
  9001.     END
  9002.  
  9003.     EXECUTE @retcode = dbo.sp_validname @publication
  9004.  
  9005.     IF @@ERROR <> 0 OR @retcode <> 0
  9006.        RETURN (1)
  9007.  
  9008.     /*
  9009.     ** Parameter Check: @subscriber and @subscriber_db
  9010.     */
  9011.  
  9012.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  9013.         SELECT @subscriber = @@SERVERNAME
  9014.  
  9015.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  9016.         SELECT @subscriber_db = DB_NAME()
  9017.     
  9018.     EXECUTE @retcode = dbo.sp_validname @subscriber
  9019.     IF @@ERROR <> 0 OR @retcode <> 0
  9020.        RETURN (1)
  9021.     
  9022.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  9023.     IF @@ERROR <> 0 OR @retcode <> 0
  9024.        RETURN (1)
  9025.  
  9026.     /* 
  9027.     ** Check to see if MSreplictaion_subscriptions table exists.
  9028.     ** If so, copy it into the temp table
  9029.     */
  9030.     IF  NOT EXISTS (SELECT * FROM sysobjects WHERE 
  9031.         type = 'U' AND
  9032.         name = 'MSreplication_subscriptions')
  9033.     BEGIN
  9034.         RAISERROR (20017, 16, -1)
  9035.         RETURN (1)
  9036.     END 
  9037.     
  9038.     /*
  9039.     ** Check to make sure that the subscription does exist
  9040.     */
  9041.     IF NOT EXISTS (SELECT * FROM  MSreplication_subscriptions
  9042.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  9043.                       publisher_db  = @publisher_db AND
  9044.                       publication = @publication)
  9045.     BEGIN
  9046.         RAISERROR (20017, 16, -1)
  9047.         RETURN (1)
  9048.     END
  9049.     
  9050.     declare @update_mode_id int
  9051.     SELECT  @distribution_agent = NULL
  9052.     SELECT  @independent_agent_id = independent_agent, 
  9053.             @subscription_type_id = subscription_type,
  9054.             @distribution_agent = distribution_agent,
  9055.             @update_mode_id = update_mode
  9056.         FROM  MSreplication_subscriptions
  9057.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  9058.               publisher_db  = @publisher_db AND
  9059.               publication = @publication
  9060.     /* Distribution agent for push subscriptions is at distributor side */
  9061.     IF @subscription_type_id = 0
  9062.     BEGIN
  9063.         RAISERROR (21001, 16, -1)
  9064.         RETURN (1)
  9065.     END
  9066.  
  9067.     IF @distribution_agent IS NOT NULL
  9068.     BEGIN
  9069.         RAISERROR (21002, 11, -1, @distribution_agent)
  9070.         RETURN (1)
  9071.     END
  9072.  
  9073.     -- Parameter check: @subscriber_security_mode
  9074.     if @subscriber_security_mode is null
  9075.     begin
  9076.         if ( platform() & @platform_nt ) = @platform_nt
  9077.             select @subscriber_security_mode = 1
  9078.         else
  9079.             select @subscriber_security_mode = 0
  9080.     end 
  9081.  
  9082.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 )
  9083.     begin
  9084.         RAISERROR(21038, 16, -1)
  9085.         RETURN (1)
  9086.     end
  9087.  
  9088.     if (@subscription_type_id <> 0)
  9089.     begin
  9090.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  9091.         begin
  9092.             raiserror(21344, 16, -1, '@subscriber_login')
  9093.             return (1)
  9094.         end
  9095.     end
  9096.     
  9097.     if (@distributor_security_mode = 0) and (@distributor_login IS NULL or rtrim(@distributor_login) = '')
  9098.     begin
  9099.         raiserror(3217, 16, -1, '@distributor_login')
  9100.         return (1)
  9101.     end
  9102.  
  9103.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  9104.     begin
  9105.         exec @retcode = sp_MScreate_sub_tables @property_table = 1
  9106.         if @retcode <> 0 or @@error <> 0
  9107.         return (1)
  9108.     end
  9109.  
  9110.     /* 
  9111.     ** Parameter check: @alt_snapshot_folder 
  9112.     ** @alt_snapshot_folder and @use_ftp are mutually exclusive    
  9113.     */
  9114.  
  9115.     IF @alt_snapshot_folder <> N'' AND @alt_snapshot_folder IS NOT NULL
  9116.        AND LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  9117.     BEGIN
  9118.         RAISERROR(21146, 16, -1)
  9119.         RETURN (1)
  9120.     END
  9121.  
  9122.     /* 
  9123.     ** Parameter check: @use_ftp
  9124.     ** Must be 'true' or 'false'
  9125.     */
  9126.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  9127.     BEGIN
  9128.         RAISERROR (14148, 16, -1, '@use_ftp')
  9129.         RETURN (1)
  9130.     END
  9131.     
  9132.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  9133.     BEGIN
  9134.         SELECT @use_ftp_bit = 1
  9135.     END
  9136.     ELSE
  9137.     BEGIN
  9138.         SELECT @use_ftp_bit = 0
  9139.     END
  9140.  
  9141.  
  9142.     /*
  9143.     ** Parameter check: @publication_type
  9144.     ** Must be 0 - Transactional or 1 - Snapshot
  9145.     */
  9146.     IF @publication_type NOT IN (0, 1)
  9147.     BEGIN
  9148.         RAISERROR (20033, 16, -1)
  9149.         RETURN (1)
  9150.     END
  9151.  
  9152.     /*
  9153.     ** Parameter Check: @dts_package_location
  9154.     ** Valid values:
  9155.     ** distributor
  9156.     ** subscriber
  9157.     **
  9158.     */
  9159.     IF LOWER(@dts_package_location collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('distributor', 'subscriber')
  9160.     BEGIN
  9161.         RAISERROR(21179, 16, -1)    
  9162.         RETURN (1)
  9163.     END
  9164.  
  9165.     declare @dts_package_location_id int
  9166.  
  9167.     IF LOWER(@dts_package_location collate SQL_Latin1_General_CP1_CS_AS) = 'distributor'
  9168.         SELECT @dts_package_location_id = 0
  9169.     ELSE 
  9170.         SELECT @dts_package_location_id = 1
  9171.  
  9172.     -- Have to be a push, non updatable  subscription to set DTS package name
  9173.     if @dts_package_name is not null
  9174.     begin
  9175.         if  @update_mode_id != 0
  9176.         begin
  9177.             RAISERROR(21180, 16, -1)    
  9178.             RETURN (1)
  9179.         end
  9180.     end
  9181.     
  9182.     -- Copy the passwords to new value before attempting to encrypt
  9183.     set @distributor_enc_password = @distributor_password
  9184.     IF (@encrypted_distributor_password = 0)
  9185.         -- Encrypt the password
  9186.         BEGIN
  9187.             EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_enc_password OUTPUT
  9188.             IF @@error <> 0 OR @retcode <> 0
  9189.                 return 1
  9190.         END
  9191.     
  9192.     declare @dts_package_enc_password nvarchar(524)
  9193.     set @dts_package_enc_password = @dts_package_password
  9194.  
  9195.     if @dts_package_enc_password is not null
  9196.     begin
  9197.         EXEC @retcode = master.dbo.xp_repl_encrypt @dts_package_enc_password OUTPUT
  9198.         IF @@error <> 0 OR @retcode <> 0
  9199.             return 1
  9200.     end
  9201.  
  9202.     /*
  9203.     ** Parameter Check: @offloadserver
  9204.     ** 1. If @offloadagent = 'true' then @offloadserver cannot be null.
  9205.     ** 2. Similar to the push case, we don't allow "remote" activation
  9206.     **    of agent on the local machine.
  9207.     */
  9208.     SELECT @offloadagent = LOWER(@offloadagent collate SQL_Latin1_General_CP1_CS_AS)
  9209.     IF @offloadagent NOT IN ('true', 'false')
  9210.     BEGIN
  9211.         RAISERROR (14148, 16, -1, '@offloadagent')
  9212.         RETURN (1)
  9213.     END
  9214.  
  9215.     IF @offloadagent = 'true'
  9216.     BEGIN
  9217.         SELECT @offload_agent_bit = 1
  9218.     END
  9219.     ELSE
  9220.     BEGIN
  9221.         SELECT @offload_agent_bit = 0
  9222.     END
  9223.  
  9224.     IF @offload_agent_bit = 1 AND (@offloadserver is NULL or
  9225.                                @offloadserver = N'')
  9226.     BEGIN
  9227.         RAISERROR(21215, 16, -1)
  9228.         RETURN (1)
  9229.     END
  9230.     
  9231.     IF UPPER(@offloadserver) = UPPER(@@SERVERNAME) AND
  9232.        @offload_agent_bit = 1
  9233.     BEGIN
  9234.         RAISERROR(21227, 16, -1)
  9235.         RETURN (1)
  9236.     END
  9237.  
  9238.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  9239.     IF @retcode <> 0 OR @@ERROR <> 0
  9240.         RETURN (1)
  9241.  
  9242.     /*
  9243.     ** Construct unique name
  9244.     */
  9245.     if @subscriber is NULL select @subscriber = ''
  9246.     if @subscriber_db is NULL select @subscriber_db = ''
  9247.     
  9248.     declare @job_existing bit
  9249.     if @job_name is null
  9250.     begin
  9251.         select @job_existing = 0
  9252.         SELECT @job_name = CONVERT(nvarchar(18),@publisher ) + '-' + CONVERT(nvarchar(18),@publisher_db) + '-' + 
  9253.                         CONVERT(nvarchar(18),@publication) + '-' + CONVERT(nvarchar(18),@subscriber) + '-' +
  9254.                         CONVERT(nvarchar(18),@subscriber_db) + '-' + CONVERT(nvarchar(36),newid())
  9255.     end
  9256.     else
  9257.         select @job_existing = 1
  9258.  
  9259.     -- Get property values.
  9260.     if @reserved = 'no_change_to_properties'
  9261.     begin
  9262.         -- Get the distributor value. It will be used in agent command line.
  9263.         select @distributor = distributor, 
  9264.             @enabled_for_syncmgr = case enabled_for_syncmgr
  9265.                 when 0 then 'false'
  9266.                 when 1 then 'true'
  9267.                 end
  9268.         from MSsubscription_properties where
  9269.             UPPER(publisher) = UPPER(@publisher)
  9270.             and publisher_db =  @publisher_db
  9271.             and publication = @publication              
  9272.     end
  9273.  
  9274.     BEGIN TRAN
  9275.  
  9276.     /*
  9277.     ** If the publication is independent agent type or it is the first
  9278.     ** subscription on the non independent agent publications.
  9279.     */
  9280.  
  9281.     IF @independent_agent_id = 1 OR 
  9282.         NOT EXISTS (SELECT * FROM MSreplication_subscriptions WHERE
  9283.                             UPPER(@publisher) = UPPER(publisher) and
  9284.                             @publisher_db = publisher_db and
  9285.                             agent_id IS NOT NULL and
  9286.                             independent_agent = 0)
  9287.     BEGIN
  9288.         if @job_existing = 0
  9289.         begin
  9290.             /* Construct agent command */
  9291.             SELECT @command = '-Publisher ' + @publisher + ' '
  9292.             SELECT @command = @command + '-PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  9293.             IF @independent_agent_id = 1
  9294.                 SELECT @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  9295.  
  9296.             SELECT @command = @command + '-Distributor ' + QUOTENAME(@distributor)  + ' '
  9297.  
  9298.             /*
  9299.             Use -Xdatabase to save command line space
  9300.             We can not use -Xserver for distribution because SQLExec will validate the server
  9301.             to be in sysservers.
  9302.  
  9303.             SELECT @command = @command + '-DistributionDB ' + QUOTENAME(@distribution_db)  + ' '
  9304.             */
  9305.             
  9306.             SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10),@subscription_type_id)  + ' '
  9307.             SELECT @command = @command + '-Subscriber ' + QUOTENAME(@subscriber)  + ' '
  9308.         
  9309.             select @command = @command + '-SubscriberSecurityMode ' + 
  9310.                 convert(nvarchar(10),@subscriber_security_mode) + ' '
  9311.             if @subscriber_login is not NULL
  9312.                 select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  9313.             if @subscriber_password is not NULL
  9314.             begin
  9315.                 set @subscriber_enc_password = @subscriber_password
  9316.                 exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  9317.                 select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  9318.             end
  9319.  
  9320.             SELECT @command = @command + '-SubscriberDB ' + QUOTENAME(@subscriber_db) + ' '
  9321.  
  9322.                     
  9323.             if @dts_package_name is not null
  9324.               select @command = @command + '-UseDTS '
  9325.  
  9326.             if @offload_agent_bit = 1 
  9327.                 select @command = @command + N'-Offload ' + @offloadserver + N' '
  9328.  
  9329.             /* 
  9330.             ** make sure the command line is not truncated
  9331.             */
  9332.             /* Use datalength because len doesn't count the last space in @command */
  9333.             IF (datalength(@command) + datalength(@optional_command_line)) > 8000
  9334.             BEGIN
  9335.                 RAISERROR(20018, 16, -1)
  9336.                 RETURN(1)
  9337.             END
  9338.  
  9339.             SELECT @command = @command + @optional_command_line
  9340.  
  9341.             -- Get Distribution category name (assumes category_id = 10)
  9342.             select @category_name = name FROM msdb.dbo.syscategories where category_id = 10
  9343.  
  9344.             EXEC @retcode = dbo.sp_MSadd_repl_job
  9345.                     @name = @job_name,
  9346.                     @subsystem = 'Distribution',
  9347.                     @server = @@SERVERNAME,
  9348.                     @databasename = @distribution_db,
  9349.                     @enabled = 1,
  9350.                     @freqtype = @frequency_type,
  9351.                     @freqinterval = @frequency_interval,
  9352.                     @freqsubtype = @frequency_subday,
  9353.                     @freqsubinterval = @frequency_subday_interval,
  9354.                     @freqrelativeinterval = @frequency_relative_interval,
  9355.                     @freqrecurrencefactor = @frequency_recurrence_factor,
  9356.                     @activestartdate = @active_start_date,
  9357.                     @activeenddate = @active_end_date,
  9358.                     @activestarttimeofday = @active_start_time_of_day,
  9359.                     @activeendtimeofday = @active_end_time_of_day,
  9360.                     @command = @command,
  9361.                     @category_name = @category_name,
  9362.                     @retryattempts = 10,
  9363.                     @retrydelay = 1,
  9364.                     @job_id = @distribution_jobid OUTPUT
  9365.  
  9366.             IF @@ERROR <> 0 or @retcode <> 0
  9367.             BEGIN
  9368.                 IF @@TRANCOUNT = 1
  9369.                     ROLLBACK TRAN
  9370.                 ELSE
  9371.                     COMMIT TRAN   
  9372.                 RETURN(1)
  9373.             END
  9374.         end
  9375.         else
  9376.         begin
  9377.             select @distribution_jobid = job_id from msdb..sysjobs_view where 
  9378.                 name = @job_name collate database_default and
  9379.                 UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  9380.             if @distribution_jobid IS NULL
  9381.             begin
  9382.                 -- Message from msdb.dbo.sp_verify_job_identifiers
  9383.                 RAISERROR(14262, -1, -1, 'Job', @job_name)          
  9384.                 IF @@TRANCOUNT = 1
  9385.                     ROLLBACK TRAN
  9386.                 ELSE
  9387.                     COMMIT TRAN   
  9388.                 RETURN(1)
  9389.             end
  9390.         end
  9391.     END
  9392.  
  9393.     if @reserved <> 'no_change_to_properties' and (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  9394.     BEGIN
  9395.         IF NOT EXISTS (select * from MSsubscription_properties 
  9396.             where UPPER(publisher) = UPPER(@publisher)
  9397.               and publisher_db =  @publisher_db
  9398.               and publication = @publication) 
  9399.         BEGIN
  9400.             -- Publication type:
  9401.             -- 0  transactional
  9402.             -- 1  snapshot
  9403.             -- 2  merge (not allowed)
  9404.  
  9405.             INSERT INTO MSsubscription_properties 
  9406.             (publisher, publisher_db, publication, publication_type, 
  9407.              publisher_login,publisher_password, publisher_security_mode, 
  9408.              distributor, distributor_login, distributor_password, 
  9409.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  9410.              ftp_password, alt_snapshot_folder, working_directory, use_ftp,
  9411.              dts_package_name, dts_package_password, dts_package_location, 
  9412.              offload_agent, offload_server, dynamic_snapshot_location)
  9413.             values (@publisher, @publisher_db, @publication, @publication_type, NULL, NULL, 1, 
  9414.                 @distributor, @distributor_login, @distributor_enc_password, 
  9415.                 @distributor_security_mode, null, null, null,
  9416.                 null, @alt_snapshot_folder, @working_directory, @use_ftp_bit,
  9417.                 @dts_package_name, @dts_package_enc_password, 
  9418.                 @dts_package_location_id, @offload_agent_bit, @offloadserver, null)
  9419.  
  9420.             IF @@ERROR <> 0 
  9421.             BEGIN
  9422.                 IF @@TRANCOUNT = 1
  9423.                     ROLLBACK TRAN
  9424.                 ELSE
  9425.                     COMMIT TRAN           
  9426.                 RETURN(1)
  9427.             END
  9428.         END
  9429.         ELSE
  9430.         BEGIN
  9431.             update MSsubscription_properties set
  9432.                 distributor = @distributor,
  9433.                 distributor_login = @distributor_login,
  9434.                 distributor_password = @distributor_enc_password,
  9435.                 distributor_security_mode = @distributor_security_mode,
  9436.                 dts_package_name = @dts_package_name,
  9437.                 dts_package_password = @dts_package_enc_password,
  9438.                 dts_package_location = @dts_package_location_id
  9439.                 where UPPER(publisher) = UPPER(@publisher)
  9440.                     and publisher_db =  @publisher_db
  9441.                     and publication = @publication
  9442.         END
  9443.  
  9444.  
  9445.         -- For dependent subscriptions we need to fix up all the
  9446.         -- shared properties  
  9447.         IF @independent_agent_id = 0 
  9448.         BEGIN
  9449.  
  9450.             EXEC @retcode = sp_MSfixupsharedagentproperties
  9451.                    @publisher = @publisher,
  9452.                    @publisher_db = @publisher_db,
  9453.                    @publication = @publication,
  9454.                    @distributor = @distributor,
  9455.                    @distributor_security_mode = @distributor_security_mode,
  9456.                    @distributor_login = @distributor_login,
  9457.                    @distributor_password = @distributor_enc_password,
  9458.                    @ftp_address = @ftp_address,
  9459.                    @ftp_port = @ftp_port,
  9460.                    @ftp_login = @ftp_login,
  9461.                    @ftp_password = @ftp_password,
  9462.                    @alt_snapshot_folder = @alt_snapshot_folder,
  9463.                    @working_directory = @working_directory,
  9464.                    @use_ftp = @use_ftp_bit,
  9465.                    @offload_agent = @offload_agent_bit,
  9466.                    @offload_server = @offloadserver
  9467.                     
  9468.             IF @retcode <> 0 OR @@ERROR <> 0
  9469.             BEGIN
  9470.             IF @@TRANCOUNT = 1
  9471.                 ROLLBACK TRAN
  9472.             ELSE
  9473.                 COMMIT TRAN           
  9474.             RETURN(1)
  9475.             END
  9476.         END
  9477.  
  9478.         IF @@ERROR <> 0 
  9479.         BEGIN
  9480.             IF @@TRANCOUNT = 1
  9481.                 ROLLBACK TRAN
  9482.             ELSE
  9483.                 COMMIT TRAN           
  9484.             RETURN(1)
  9485.         END
  9486.     END
  9487.  
  9488.  
  9489.     /* If we do not have independent agents , i.e. independent_agent=0, but there is
  9490.     already a row for that publisher and that publisher database with a NOT null 
  9491.     distribution_agent_id, then set the @distribution_jobid to that id.  Note that if
  9492.     there are no rows returned, the value of the variable does not change, which is what we want.
  9493.     There should never be more than one row ever returned for this query - but will use TOP 1
  9494.     to insist that is the case.
  9495.     */
  9496.     
  9497.     IF @independent_agent_id = 0
  9498.     BEGIN
  9499.         SELECT DISTINCT @distribution_jobid=agent_id, @job_name = distribution_agent 
  9500.           FROM MSreplication_subscriptions
  9501.          WHERE UPPER(publisher) = UPPER(@publisher) 
  9502.            AND publisher_db =  @publisher_db
  9503.            AND agent_id IS NOT NULL AND independent_agent=0
  9504.     
  9505.     END
  9506.  
  9507.     UPDATE MSreplication_subscriptions 
  9508.        SET distribution_agent = @job_name,
  9509.            agent_id = @distribution_jobid
  9510.      WHERE UPPER(publisher) = UPPER(@publisher) 
  9511.        AND publisher_db =  @publisher_db 
  9512.        AND publication =  @publication 
  9513.        AND (subscription_type = 1 /* pull*/ OR subscription_type = 2) /*anonymous*/
  9514.  
  9515.     IF @@ERROR <> 0 
  9516.     BEGIN
  9517.         IF @@TRANCOUNT = 1
  9518.             ROLLBACK TRAN
  9519.         ELSE
  9520.             COMMIT TRAN           
  9521.         RETURN(1)
  9522.     END 
  9523.  
  9524.     /* Conditional support for MobileSync */
  9525.     if LOWER(@enabled_for_syncmgr collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  9526.     BEGIN
  9527.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  9528.         declare @subscription_id uniqueidentifier
  9529.         declare @failover_mode_id int
  9530.         set @subscription_id = convert(uniqueidentifier, @distribution_jobid)
  9531.  
  9532.         if @update_mode_id in (3,5) 
  9533.             select @failover_mode_id = 1
  9534.         else if @update_mode_id in (2,4)
  9535.             select @failover_mode_id = 2
  9536.         else
  9537.             select @failover_mode_id = 0
  9538.             
  9539.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 1,
  9540.                                     @publisher = @publisher,
  9541.                                     @publisher_db = @publisher_db,
  9542.                                     @publication = @publication,
  9543.                                     @subscriber = @subscriber,
  9544.                                     @subscriber_db = @subscriber_db,
  9545.                                     @subscriber_security_mode = @subscriber_security_mode,
  9546.                                     @subscriber_login = @subscriber_login,
  9547.                                     @subscriber_password = @subscriber_password,
  9548.                                     @distributor = @distributor,
  9549.                                     @subscription_id = @subscription_id,
  9550.                                     @independent_agent = @independent_agent_id,
  9551.                                     @subscription_type = @subscription_type_id,
  9552.                                     @failover_mode = @failover_mode_id
  9553.         IF @@ERROR <> 0 or @retcode <> 0
  9554.         BEGIN
  9555.             IF @@TRANCOUNT = 1
  9556.                 ROLLBACK TRAN
  9557.             ELSE
  9558.                 COMMIT TRAN           
  9559.             RETURN(1)
  9560.         END
  9561.     END
  9562.  
  9563.     COMMIT TRAN
  9564.     RETURN(0)
  9565. GO
  9566.  
  9567.  
  9568.  
  9569.  
  9570.  
  9571.  
  9572. raiserror('Creating procedure sp_helpsubscription_properties
  9573. ', 0,1)
  9574. go
  9575. CREATE PROCEDURE sp_helpsubscription_properties
  9576.         @publisher sysname = '%', 
  9577.         @publisher_db sysname = '%', 
  9578.         @publication sysname = '%', 
  9579.         @publication_type int = NULL
  9580.     AS
  9581.  
  9582.     SET NOCOUNT ON
  9583.     DECLARE @retcode int
  9584.  
  9585.     /*
  9586.     ** Security Check
  9587.     */
  9588.  
  9589.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  9590.     IF @@ERROR <> 0 or @retcode <> 0
  9591.         RETURN(1)
  9592.  
  9593.     /*
  9594.     ** The logic is added here for the case where MSsubscription_properties table does not exist
  9595.     ** or relevant entry is not added because sp_addmergepullsubscription_agent or sp_addsubscription_agent
  9596.     ** is not called.
  9597.     */
  9598.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  9599.     begin
  9600.         return (0)
  9601.     end
  9602.  
  9603.     IF (@publisher IS NULL) OR (@publisher = '')
  9604.         select @publisher = '%'
  9605.     IF (@publisher_db IS NULL) OR (@publisher_db = '')
  9606.         select @publisher_db = '%'
  9607.     IF (@publication IS NULL) OR (@publication = '')
  9608.         select @publication = '%'
  9609.  
  9610.     IF @publication_type IS NOT NULL
  9611.     BEGIN
  9612.         SELECT publisher, publisher_db, publication, publication_type, publisher_login,
  9613.                publisher_password, publisher_security_mode, distributor, distributor_login,
  9614.                distributor_password, distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0,
  9615.                'ftp_login' = null, 'ftp_password' = null, alt_snapshot_folder, working_directory, use_ftp,
  9616.                dts_package_name, dts_package_password, dts_package_location, 
  9617.                offload_agent, offload_server, dynamic_snapshot_location 
  9618.           FROM MSsubscription_properties
  9619.          WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher)))
  9620.            AND ((@publisher_db = N'%') or ( publisher_db = @publisher_db))
  9621.            AND publication LIKE @publication
  9622.            AND publication_type = @publication_type
  9623.     END
  9624.     ELSE
  9625.     BEGIN
  9626.         SELECT publisher, publisher_db, publication, publication_type, publisher_login,
  9627.                publisher_password, publisher_security_mode, distributor, distributor_login,
  9628.                distributor_password, distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0,
  9629.                'ftp_login' = null, 'ftp_password' = null, alt_snapshot_folder, working_directory, use_ftp,
  9630.                dts_package_name, dts_package_password, dts_package_location,
  9631.                offload_agent, offload_server, dynamic_snapshot_location
  9632.           FROM MSsubscription_properties
  9633.          WHERE ((@publisher = N'%') OR (UPPER(publisher) = UPPER(@publisher)))
  9634.            AND ((@publisher_db = N'%') or ( publisher_db = @publisher_db))
  9635.            AND publication LIKE @publication
  9636.     END
  9637.  
  9638.     RETURN (0)
  9639. GO
  9640.  
  9641. EXEC dbo.sp_MS_marksystemobject sp_helpsubscription_properties
  9642. GO
  9643.  
  9644. raiserror('Creating procedure sp_change_subscription_properties', 0,1)
  9645. go
  9646. CREATE PROCEDURE sp_change_subscription_properties
  9647.         @publisher sysname, 
  9648.         @publisher_db sysname, 
  9649.         @publication sysname, 
  9650.         @property sysname,
  9651.         @value nvarchar(1000),
  9652.         @publication_type int = NULL
  9653.     AS
  9654.     SET NOCOUNT ON
  9655.  
  9656.     DECLARE @command nvarchar(2000)
  9657.     DECLARE @column_to_update nvarchar(64)
  9658.     DECLARE @value_string nvarchar(255)
  9659.     DECLARE @independent_agent bit
  9660.     DECLARE @retcode int
  9661.     DECLARE @subscription_type int
  9662.     DECLARE @intvalue int
  9663.     DECLARE @value_bit bit
  9664.     DECLARE @offload_agent bit
  9665.     DECLARE @offload_server sysname 
  9666.     DECLARE @dbname sysname
  9667.     DECLARE @local_publication sysname
  9668.     DECLARE @agentid binary(16)
  9669.     DECLARE @local_publisher sysname
  9670.     DECLARE @cursor_opened bit 
  9671.     DECLARE @cursor_allocated bit
  9672.     DECLARE @agenttype nvarchar(20)
  9673.     DECLARE @commandline nvarchar(3200)
  9674.  
  9675.     SELECT @cursor_opened = 0
  9676.     SELECT @cursor_allocated = 0
  9677.     SELECT @retcode = 0    
  9678.     /*
  9679.     ** Security Check
  9680.     */
  9681.  
  9682.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  9683.     IF @@ERROR <> 0 or @retcode <> 0
  9684.         RETURN(1)
  9685.  
  9686.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  9687.     begin
  9688.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  9689.         return (1)
  9690.     end
  9691.     
  9692.     if (@publisher is null)
  9693.     begin
  9694.         raiserror(14043, 16, -1, '@publisher')
  9695.         return (1)
  9696.     end
  9697.  
  9698.     if(@publisher_db is null)
  9699.     begin
  9700.         raiserror(14043, 16, -1, '@publisher_db')
  9701.         return (1)
  9702.     end
  9703.     
  9704.     if (@publication is null) or (@publication = '')
  9705.     begin
  9706.         select @publication = '%'
  9707.     end
  9708.  
  9709.  
  9710.     -- Expand '%' into individual subscriptions using a cursor
  9711.     IF @publication = N'%'
  9712.     BEGIN
  9713.  
  9714.         BEGIN TRANSACTION subscription_properties_exp
  9715.         DECLARE hsubprop CURSOR LOCAL FAST_FORWARD FOR
  9716.             SELECT publication 
  9717.               FROM MSreplication_subscriptions
  9718.              WHERE UPPER(publisher) = UPPER(@publisher)
  9719.                AND publisher_db = @publisher_db
  9720.                -- NOTE:  publication like '%' is implicit
  9721.         IF @@ERROR <> 0
  9722.             GOTO ExpFailure
  9723.         SELECT @cursor_allocated = 1
  9724.     
  9725.         OPEN hsubprop
  9726.         IF @@ERROR <> 0
  9727.             GOTO ExpFailure    
  9728.         SELECT @cursor_opened = 1
  9729.  
  9730.         FETCH hsubprop INTO @local_publication
  9731.         WHILE (@@FETCH_STATUS <> 0)
  9732.         BEGIN
  9733.                             
  9734.             EXEC @retcode = sp_change_subscription_properties
  9735.                 @publisher = @publisher,
  9736.                 @publisher_db = @publisher_db,
  9737.                 @publication = @local_publication,
  9738.                 @property = @property,
  9739.                 @value = @value,
  9740.                 @publication_type = @publication_type
  9741.             IF @retcode <> 0 OR @@ERROR <> 0
  9742.                 GOTO ExpFailure
  9743.             FETCH hsubprop INTO @local_publication
  9744.         END
  9745.  
  9746.         CLOSE hsubprop
  9747.         DEALLOCATE hsubprop
  9748.         COMMIT TRANSACTION subscription_properties_exp
  9749.         IF @@ERROR <> 0
  9750.             GOTO ExpFailure
  9751.  
  9752.         RETURN (0)
  9753. ExpFailure:
  9754.  
  9755.         IF @cursor_opened = 1
  9756.             CLOSE hsubprop
  9757.         IF @cursor_allocated = 1
  9758.             DEALLOCATE hsubprop
  9759.         ROLLBACK TRANSACTION subscription_properties_exp        
  9760.         RETURN (1)
  9761.     END    
  9762.  
  9763.     -- Check for existence of the specified pull subscription
  9764.     SELECT @agentid = NULL
  9765.     SELECT @local_publisher = NULL
  9766.     SELECT @dbname = DB_NAME()
  9767.  
  9768.     IF @publication_type IN (0,1) OR @publication_type IS NULL
  9769.     BEGIN
  9770.         IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('MSreplication_subscriptions'))
  9771.         BEGIN
  9772.             SELECT @local_publisher = publisher, 
  9773.                    @agentid = agent_id
  9774.               FROM MSreplication_subscriptions
  9775.              WHERE UPPER(publisher) = UPPER(@publisher)
  9776.                AND publisher_db = @publisher_db
  9777.                AND publication = @publication 
  9778.         END
  9779.  
  9780.     END
  9781.  
  9782.     IF @publication_type = 2 OR (@publication_type IS NULL AND
  9783.         @local_publisher IS NULL)
  9784.     BEGIN
  9785.         IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id('sysmergepublications'))
  9786.         BEGIN
  9787.  
  9788.             SELECT @local_publisher = mp.publisher,
  9789.                    @agentid = mr.merge_jobid
  9790.               FROM sysmergepublications mp
  9791.             INNER JOIN sysmergesubscriptions ms
  9792.                 ON mp.pubid = ms.pubid 
  9793.                AND UPPER(mp.publisher) = UPPER(@publisher) 
  9794.                AND mp.publisher_db = @publisher_db
  9795.                AND mp.name = @publication 
  9796.                AND ms.db_name = @dbname
  9797.                AND UPPER(ms.subscriber_server) = UPPER(@@SERVERNAME)
  9798.             INNER JOIN MSmerge_replinfo mr
  9799.                 ON ms.subid = mr.repid
  9800.         END
  9801.     END 
  9802.  
  9803.     IF @local_publisher IS NULL
  9804.     BEGIN
  9805.         RAISERROR(21226, 16, -1, @dbname)
  9806.         RETURN (1)
  9807.     END
  9808.  
  9809.     SELECT @offload_agent = NULL
  9810.     SELECT @offload_server = NULL
  9811.     SELECT @offload_agent = offload_agent, 
  9812.            @offload_server = offload_server,
  9813.            @publication_type = publication_type             
  9814.       FROM MSsubscription_properties 
  9815.      WHERE UPPER(publisher) = UPPER(@publisher)
  9816.        AND publisher_db = @publisher_db
  9817.        AND publication = @publication
  9818.     
  9819.     -- If the subscription does not have a corresponding entry in MSsubscription_properties, 
  9820.     -- the subscription is probably created by the ActiveX control. In this case there isn't much
  9821.     -- we can do about it so we just return 0.
  9822.     IF @offload_agent IS NULL
  9823.     BEGIN
  9824.         RETURN (0)
  9825.     END      
  9826.     
  9827.     IF (@property IS NULL)
  9828.     begin
  9829.         raiserror(14043, 16, -1, '@property')
  9830.         return (1)
  9831.     end
  9832.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_login')
  9833.         select @column_to_update = 'publisher_login'
  9834.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_password')
  9835.     begin
  9836.         select @column_to_update = 'publisher_password'
  9837.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  9838.         IF @@error <> 0 OR @retcode <> 0
  9839.             return 1
  9840.     end
  9841.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode')
  9842.         select @column_to_update = 'publisher_security_mode'
  9843.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor')
  9844.         select @column_to_update = 'distributor'
  9845.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_login')
  9846.         select @column_to_update = 'distributor_login'
  9847.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_password')
  9848.     begin
  9849.         select @column_to_update = 'distributor_password'
  9850.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  9851.         IF @@error <> 0 OR @retcode <> 0
  9852.             return 1
  9853.     end
  9854.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_security_mode')
  9855.         select @column_to_update = 'distributor_security_mode'
  9856.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_address')
  9857.         select @column_to_update = 'ftp_address'
  9858.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_port')
  9859.         select @column_to_update = 'ftp_port'
  9860.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_login')
  9861.         select @column_to_update = 'ftp_login'
  9862.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'ftp_password')
  9863.         select @column_to_update = 'ftp_password'
  9864.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'alt_snapshot_folder')
  9865.     BEGIN
  9866.         select @column_to_update = 'alt_snapshot_folder'
  9867.     END
  9868.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'working_directory')
  9869.     BEGIN
  9870.         select @column_to_update = 'working_directory'
  9871.     END
  9872.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_ftp')
  9873.         select @column_to_update = 'use_ftp'
  9874.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_name')
  9875.         select @column_to_update = 'dts_package_name'
  9876.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_password')
  9877.     begin
  9878.         select @column_to_update = 'dts_package_password'
  9879.         EXEC @retcode = master.dbo.xp_repl_encrypt @value OUTPUT
  9880.         IF @@error <> 0 OR @retcode <> 0
  9881.             return 1
  9882.     end
  9883.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_location')
  9884.         select @column_to_update = 'dts_package_location'
  9885.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_agent')
  9886.     BEGIN
  9887.         select @column_to_update = 'offload_agent'
  9888.     END
  9889.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_server')
  9890.     BEGIN
  9891.         select @column_to_update = 'offload_server'
  9892.         exec @retcode = sp_MSreplcheckoffloadserver @value
  9893.         if @retcode <> 0 or @@error <> 0
  9894.                 return(1)
  9895.     END
  9896.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = N'dynamic_snapshot_location') and @publication_type = 2
  9897.     BEGIN
  9898.         select @column_to_update = N'dynamic_snapshot_location'
  9899.     END
  9900.     ELSE
  9901.     BEGIN
  9902.         raiserror (3217, 16, -1, '@property')
  9903.         return(1)
  9904.     END
  9905.  
  9906.     IF @column_to_update in ('use_ftp', 'offload_agent')
  9907.     BEGIN
  9908.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  9909.         BEGIN
  9910.             SELECT @value_bit = 1
  9911.         END
  9912.         ELSE IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'false'
  9913.         BEGIN
  9914.             SELECT @value_bit = 0
  9915.         END
  9916.         ELSE
  9917.         BEGIN 
  9918.             RAISERROR(14137, 16, -1)
  9919.         END
  9920.     END
  9921.  
  9922.     IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'distributor_security_mode') OR (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode') 
  9923.     BEGIN
  9924.         IF NOT ( @value = 0 or @value = 1 or (@value = 2 and lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'publisher_security_mode' )) 
  9925.         BEGIN
  9926.             raiserror(3217, 16, -1, '@value')
  9927.             return(1)
  9928.         END
  9929.         select @value_string = convert(nvarchar(1), @value)
  9930.     END
  9931.     ELSE IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'dts_package_location')
  9932.     BEGIN
  9933.         IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'distributor' 
  9934.             select @value_string = '0'
  9935.         ELSE IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = N'subscriber' 
  9936.             select @value_string = '1'
  9937.         ELSE 
  9938.         begin
  9939.             raiserror(20587, 16, -1, 'dts_package_location', 'sp_change_subscription_properties')
  9940.             return(1)
  9941.         end
  9942.  
  9943.     END
  9944.     ELSE
  9945.     BEGIN
  9946.         IF @value IS NULL
  9947.         BEGIN
  9948.             select @value_string = 'null'
  9949.         END
  9950.         ELSE
  9951.         BEGIN
  9952.             select @value_string = 'N' + quotename(rtrim(@value),'''')
  9953.         END
  9954.     END    
  9955.  
  9956.     -- Ignore ftp_address, ftp_port, ftp_login, ftp_password on post 7.0 servers
  9957.     IF (@column_to_update IN (N'ftp_address', N'ftp_port', N'ftp_login', N'ftp_password'))
  9958.     BEGIN
  9959.         RETURN (0)
  9960.     END
  9961.  
  9962.     -- If the 'offload_agent' property is 1, 'offload_server' property must not be
  9963.     -- null or empty. Make sure that this is the case
  9964.     IF (@column_to_update = N'offload_agent' AND 
  9965.         @value_bit = 1 AND 
  9966.         (@offload_server IS NULL OR @offload_server = N''))
  9967.     BEGIN
  9968.         RAISERROR(21215, 16, -1)
  9969.         RETURN(1)
  9970.     END
  9971.  
  9972.     -- If we are enabling agent offload for this pull subscription, 
  9973.     -- we should make sure that the offload server is different from
  9974.     -- the Subscriber's server name
  9975.     IF (@column_to_update = N'offload_agent' AND
  9976.         @value_bit = 1 AND UPPER(@offload_server) = UPPER(@@SERVERNAME)) OR
  9977.        (@column_to_update = N'offload_server' AND
  9978.         @offload_agent = 1 AND 
  9979.         UPPER(@value) = UPPER(@@SERVERNAME))
  9980.     BEGIN
  9981.         RAISERROR(21227, 16, -1)
  9982.         RETURN (1)
  9983.     END
  9984.     
  9985. BEGIN TRANSACTION subscription_properties    
  9986.     IF (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_ftp')
  9987.     begin
  9988.         update MSsubscription_properties set use_ftp = @value_bit where 
  9989.             UPPER(publisher) = UPPER(@publisher) and 
  9990.             publisher_db = @publisher_db and
  9991.             publication = @publication 
  9992.         IF @@error <> 0 OR @retcode <> 0
  9993.             GOTO Failure
  9994.     end
  9995.     else if (lower(@property collate SQL_Latin1_General_CP1_CS_AS) = 'offload_agent')
  9996.     begin
  9997.         update MSsubscription_properties set offload_agent = @value_bit where
  9998.             UPPER(publisher) = UPPER(@publisher) and
  9999.             publisher_db = @publisher_db and
  10000.             publication = @publication
  10001.         IF @@error <> 0 OR @retcode <> 0
  10002.             GOTO Failure
  10003.  
  10004.         -- Call helper procedure to add or remove the '-Offload' parameter 
  10005.         -- from the agent's command line in msdb. By now, we should 
  10006.         -- have the publication type and the agent jodid.
  10007.  
  10008.         -- Don't do anything if the offload_agent property hasn't been changed
  10009.         IF @offload_agent <> @value_bit
  10010.         BEGIN
  10011.             IF @publication_type IN (0,1)    
  10012.             BEGIN
  10013.                 SELECT @agenttype = N'distribution'
  10014.             END
  10015.             ELSE
  10016.             BEGIN
  10017.                 SELECT @agenttype = N'merge'
  10018.             END    
  10019.  
  10020.             -- Add or remove the Offload parameter based on the new value
  10021.             -- of the offload_agent property 
  10022.             IF @value_bit = 0
  10023.             BEGIN
  10024.                 EXEC @retcode = sp_MSremoveoffloadparameter
  10025.                         @job_id = @agentid,
  10026.                         @agenttype = @agenttype
  10027.  
  10028.                 IF @@ERROR <> 0 OR @retcode <> 0
  10029.                     GOTO Failure 
  10030.             END
  10031.             ELSE
  10032.             BEGIN
  10033.                 EXEC @retcode = sp_MSaddoffloadparameter 
  10034.                         @job_id = @agentid,
  10035.                         @offloadserver = @offload_server,
  10036.                         @agenttype = @agenttype
  10037.  
  10038.                 IF @@ERROR <> 0 OR @retcode <> 0
  10039.                     GOTO Failure 
  10040.             END
  10041.         END
  10042.     end
  10043.     else if lower(@property collate SQL_Latin1_General_CP1_CS_AS) = N'dynamic_snapshot_location'
  10044.     begin
  10045.         select @value = rtrim(ltrim(@value))
  10046.  
  10047.         update MSsubscription_properties 
  10048.            set dynamic_snapshot_location = @value
  10049.          where upper(publisher) = upper(@publisher) 
  10050.            and publisher_db = @publisher_db 
  10051.            and publication = @publication
  10052.         if @@error <> 0 or @retcode <> 0
  10053.             goto Failure
  10054.  
  10055.         -- Call helper functions to add/update or remove the -DynamicSnapshotLocationParameter
  10056.         if @value is null or @value = N''
  10057.         begin
  10058.             update msdb.dbo.sysjobsteps 
  10059.                set command = fn_removeparameterwithargument(command, N'DynamicSnapshotLocation') collate database_default
  10060.              where job_id = @agentid
  10061.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge'
  10062.         end
  10063.         else
  10064.         begin
  10065.  
  10066.             select @commandline = command 
  10067.               from msdb.dbo.sysjobsteps
  10068.              where job_id = @agentid
  10069.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge'
  10070.  
  10071.             select @commandline = fn_updateparameterwithargument(@commandline, N'DynamicSnapshotLocation', fn_replquotename(@value)) collate database_default
  10072.  
  10073.             -- Need to remove existing alternate snapshot folder parameters
  10074.             -- and file transfer type parameters
  10075.  
  10076.             select @commandline = fn_removeparameterwithargument(@commandline, N'FileTransferType') collate database_default
  10077.             
  10078.             select @commandline = fn_removeparameterwithargument(@commandline, N'AltSnapshotFolder') collate database_default
  10079.  
  10080.             update msdb.dbo.sysjobsteps
  10081.                set command = @commandline
  10082.              where job_id = @agentid
  10083.                and lower(subsystem collate SQL_Latin1_General_CP1_CS_AS) = N'merge' 
  10084.  
  10085.         end
  10086.     end
  10087.     else    
  10088.     begin
  10089.         -- Password is encrypted. Must prefix every string with N' 
  10090.         -- otherwise, the chars will be convert to '???'
  10091.         select @command = N'update MSsubscription_properties set ' + @column_to_update + '= ' + @value_string
  10092.                 + ' where UPPER(publisher) = UPPER(' + quotename(@publisher,'''') 
  10093.                 + ') and publisher_db = ' + quotename(@publisher_db, '''')
  10094.                 + ' and publication = ' + quotename(@publication,'''')
  10095.         EXEC (@command)
  10096.         IF @@error <> 0 OR @retcode <> 0
  10097.             GOTO Failure
  10098.     end
  10099.  
  10100.  
  10101.     -- If the offload_server property is chnaged, we have to modify the agent's
  10102.     -- command line if the agent has already been enabled for remote activation         
  10103.     IF @column_to_update = N'offload_server' AND @offload_agent = 1
  10104.     BEGIN
  10105.         IF @publication_type IN (0,1)
  10106.         BEGIN
  10107.             SELECT @agenttype = N'distribution'
  10108.         END
  10109.         ELSE
  10110.         BEGIN
  10111.             SELECT @agenttype = N'merge'
  10112.         END
  10113.  
  10114.         EXEC @retcode = sp_MSaddoffloadparameter
  10115.             @job_id = @agentid,
  10116.             @offloadserver = @value,
  10117.             @agenttype = @agenttype        
  10118.         IF @retcode <> 0 OR @@ERROR <> 0
  10119.             GOTO Failure
  10120.     END
  10121.  
  10122.     IF (@publication_type = 0 or @publication_type = 1) AND @publication <> N'%' AND
  10123.         @column_to_update IN ('distributor',
  10124.                               'distributor_login',
  10125.                               'distributor_password',
  10126.                               'distributor_security_mode',
  10127.                               'ftp_address',
  10128.                               'ftp_port',
  10129.                               'ftp_login',
  10130.                               'ftp_password',
  10131.                               'alt_snapshot_folder',
  10132.                               'working_dir',
  10133.                               'use_ftp',
  10134.                               'offload_agent',
  10135.                               'offload_server')
  10136.     BEGIN
  10137.         SELECT @subscription_type = subscription_type
  10138.           FROM MSreplication_subscriptions
  10139.          WHERE UPPER(publisher) = UPPER(@publisher)
  10140.            AND publisher_db = @publisher_db
  10141.            AND publication = @publication
  10142.         IF @@error <> 0 OR @retcode <> 0
  10143.             GOTO Failure
  10144.  
  10145.         -- Update the property for all shared subscriptions
  10146.         IF @column_to_update IN ('distributor_security_mode', 
  10147.                                  'ftp_port')
  10148.         BEGIN
  10149.             SELECT @intvalue = CONVERT(int, @value)
  10150.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10151.                     @publisher = @publisher,
  10152.                     @publisher_db = @publisher_db,
  10153.                     @publication = @publication,
  10154.                     @property = @column_to_update,
  10155.                     @intvalue = @intvalue,
  10156.                     @subscription_type = @subscription_type
  10157.         END
  10158.         ELSE IF @column_to_update IN ('use_ftp', 'offload_agent')
  10159.         BEGIN
  10160.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10161.                     @publisher = @publisher,
  10162.                     @publisher_db = @publisher_db,
  10163.                     @publication = @publication,
  10164.                     @property = @column_to_update,
  10165.                     @intvalue = @value_bit,
  10166.                     @subscription_type = @subscription_type
  10167.         END
  10168.         ELSE 
  10169.         BEGIN
  10170.             EXEC @retcode = sp_MSupdatesharedagentproperties 
  10171.                     @publisher = @publisher,
  10172.                     @publisher_db = @publisher_db,
  10173.                     @publication = @publication,
  10174.                     @property = @column_to_update,
  10175.                     @strvalue = @value,
  10176.                     @subscription_type = @subscription_type
  10177.         END  
  10178.     
  10179.         IF @@error <> 0 OR @retcode <> 0
  10180.             GOTO Failure
  10181.     END
  10182.  
  10183.     -- Ftp and alternate snapshot folder are mutually 
  10184.     -- exclusive options but instead of raising an error
  10185.     -- when both of them are non-null, nullify the other 
  10186.     -- property when either one of them is set to non-null
  10187.     -- value since properties can only be set one at a time
  10188.  
  10189.     -- 'dynamic_snapshot_location' should also be added to the
  10190.     -- list of mutually exclusive properties
  10191.  
  10192.  
  10193.     IF (@column_to_update = 'ftp_address') AND (@value <> N''
  10194.        AND @value IS NOT NULL)
  10195.     BEGIN
  10196.         EXEC @retcode = sp_change_subscription_properties 
  10197.                 @publisher = @publisher,
  10198.                 @publisher_db = @publisher_db,
  10199.                 @publication = @publication,
  10200.                 @property = 'alt_snapshot_folder',
  10201.                 @value = NULL
  10202.  
  10203.         IF @@error <> 0 OR @retcode <> 0
  10204.             GOTO Failure
  10205.     END
  10206.  
  10207.     IF (@column_to_update = 'use_ftp') AND (@value_bit = 1)
  10208.     BEGIN
  10209.         EXEC @retcode = sp_change_subscription_properties 
  10210.                 @publisher = @publisher,
  10211.                 @publisher_db = @publisher_db,
  10212.                 @publication = @publication,
  10213.                 @property = 'alt_snapshot_folder',
  10214.                 @value = NULL
  10215.  
  10216.         IF @@error <> 0 OR @retcode <> 0
  10217.             GOTO Failure
  10218.  
  10219.         IF @publication_type = 2
  10220.         BEGIN
  10221.             EXEC @retcode = sp_change_subscription_properties
  10222.                     @publisher = @publisher,
  10223.                     @publisher_db = @publisher_db,
  10224.                     @publication = @publication,
  10225.                     @property = 'dynamic_snapshot_location',
  10226.                     @value = NULL
  10227.             IF @@error <> 0 OR @retcode <> 0
  10228.                 GOTO Failure
  10229.         END
  10230.     END
  10231.  
  10232.     IF (@column_to_update = 'alt_snapshot_folder') AND (@value <> N''
  10233.        AND @value IS NOT NULL)
  10234.     BEGIN
  10235.         EXEC @retcode = sp_change_subscription_properties 
  10236.                 @publisher = @publisher,
  10237.                 @publisher_db = @publisher_db,
  10238.                 @publication = @publication,
  10239.                 @property = 'ftp_address',
  10240.                 @value = NULL
  10241.  
  10242.         IF @@error <> 0 OR @retcode <> 0
  10243.             GOTO Failure
  10244.  
  10245.         EXEC @retcode = sp_change_subscription_properties 
  10246.                 @publisher = @publisher,
  10247.                 @publisher_db = @publisher_db,
  10248.                 @publication = @publication,
  10249.                 @property = 'use_ftp',
  10250.                 @value = 'false'
  10251.  
  10252.         IF @@error <> 0 OR @retcode <> 0
  10253.             GOTO Failure
  10254.  
  10255.         IF @publication_type = 2
  10256.         BEGIN
  10257.             EXEC @retcode = sp_change_subscription_properties
  10258.                     @publisher = @publisher,
  10259.                     @publisher_db = @publisher_db,
  10260.                     @publication = @publication,
  10261.                     @property = 'dynamic_snapshot_location',
  10262.                     @value = NULL
  10263.             IF @@error <> 0 OR @retcode <> 0
  10264.                 GOTO Failure
  10265.         END
  10266.     END
  10267.  
  10268.  
  10269.     IF (@column_to_update = 'dynamic_snapshot_location') AND (@value <> N''
  10270.         AND @value IS NOT NULL)
  10271.     BEGIN
  10272.  
  10273.         EXEC @retcode = sp_change_subscription_properties
  10274.                 @publisher = @publisher,
  10275.                 @publisher_db = @publisher_db,
  10276.                 @publication = @publication,
  10277.                 @property = 'ftp_address',
  10278.                 @value = NULL
  10279.             
  10280.         IF @@error <> 0 OR @retcode <> 0
  10281.             GOTO Failure
  10282.  
  10283.         EXEC @retcode = sp_change_subscription_properties
  10284.                 @publisher = @publisher,
  10285.                 @publisher_db = @publisher_db,
  10286.                 @publication = @publication,
  10287.                 @property = 'use_ftp',
  10288.                 @value = 'false'
  10289.             
  10290.         IF @@error <> 0 OR @retcode <> 0
  10291.             GOTO Failure
  10292.  
  10293.         EXEC @retcode = sp_change_subscription_properties
  10294.                 @publisher = @publisher,
  10295.                 @publisher_db = @publisher_db,
  10296.                 @publication = @publication,
  10297.                 @property = 'alt_snapshot_folder',
  10298.                 @value = NULL
  10299.             
  10300.         IF @@error <> 0 OR @retcode <> 0
  10301.             GOTO Failure
  10302.  
  10303.     END
  10304.  
  10305.  
  10306.     -- Turn off the offload agent bit if the 
  10307.     -- the new value of offload server happens to be null
  10308.     -- or empty
  10309.     IF (@column_to_update = 'offload_server' AND 
  10310.         (@value IS NULL OR @value = N'') AND
  10311.         @offload_agent = 1)
  10312.     BEGIN
  10313.         EXEC @retcode = sp_change_subscription_properties
  10314.                 @publisher = @publisher,
  10315.                 @publisher_db = @publisher_db,
  10316.                 @publication = @publication,
  10317.                 @property = 'offload_agent',
  10318.                 @value = 'false'
  10319.         IF @@error <> 0 OR @retcode <> 0
  10320.             GOTO Failure
  10321.     END
  10322.  
  10323.     IF @@error <> 0 OR @retcode <> 0
  10324.         GOTO Failure
  10325.  
  10326.     COMMIT TRANSACTION subscription_properties
  10327.     RETURN (0)
  10328.             
  10329. Failure:        
  10330.     ROLLBACK TRANSACTION subscription_properties
  10331.     RETURN (1)
  10332. GO
  10333. EXEC dbo.sp_MS_marksystemobject sp_change_subscription_properties
  10334. GO
  10335. grant execute on dbo.sp_change_subscription_properties to public
  10336.  
  10337. raiserror('Creating procedure sp_MSget_pullsubsagent_owner', 0,1)
  10338. go
  10339.  
  10340. CREATE PROCEDURE sp_MSget_pullsubsagent_owner (
  10341.     @publisher    sysname,
  10342.     @publisher_db sysname,
  10343.     @publication  sysname,   /* publication name */
  10344.     @owner_sid    varbinary(85) OUTPUT 
  10345.     ) AS
  10346.  
  10347.     declare @job_id uniqueidentifier
  10348.     set nocount on
  10349.  
  10350.     select @owner_sid = null
  10351.         
  10352.  
  10353.     if exists (select * from sysobjects 
  10354.                where type = 'U' and 
  10355.                      name = 'MSreplication_subscriptions')
  10356.     begin 
  10357.         -- Get the job_id corresponding to the publication
  10358.         select @job_id = agent_id
  10359.         from MSreplication_subscriptions
  10360.         where upper(@publisher) = upper(publisher) and
  10361.             @publisher_db = publisher_db and
  10362.             @publication = publication 
  10363.  
  10364.         -- Using the job_id in MSsubscription properties to get the owner_sid 
  10365.         -- in msdb..sysjobs    
  10366.         select @owner_sid = owner_sid
  10367.         from  msdb..sysjobs
  10368.         where @job_id = job_id
  10369.     end            
  10370. go 
  10371.  
  10372. exec dbo.sp_MS_marksystemobject 'sp_MSget_pullsubsagent_owner'
  10373.  
  10374. raiserror('Creating procedure sp_droppullsubscription', 0,1)
  10375. go
  10376.  
  10377. CREATE PROCEDURE sp_droppullsubscription (
  10378.     @publisher sysname,
  10379.     @publisher_db sysname,
  10380.     @publication sysname,   /* publication name */
  10381.     @reserved bit = 0
  10382.     ) AS
  10383.  
  10384.     SET NOCOUNT ON
  10385.  
  10386.     /*
  10387.     ** Declarations.
  10388.     */
  10389.  
  10390.  
  10391.     DECLARE @name nvarchar(255)
  10392.     DECLARE @retcode int
  10393.     DECLARE @agent_id binary(16)
  10394.     DECLARE @publisher_ex sysname          /* Expression used in the cursor */
  10395.     DECLARE @publisher_db_ex sysname     /* Expression used in the cursor */
  10396.     DECLARE @publication_ex sysname      /* Expression used in the cursor */
  10397.     DECLARE @expanded bit
  10398.     DECLARE @subscription_type_id int
  10399.     DECLARE @count_sub int
  10400.     DECLARE @drop_null_pub bit
  10401.     DECLARE @drop_push_bit bit
  10402.     DECLARE @push int
  10403.     DECLARE @implicit_transaction int
  10404.     DECLARE @close_cursor_at_commit int
  10405.     DECLARE @owner_sid varbinary(85)
  10406.     DECLARE @owner_name sysname
  10407.     DECLARE @qualified_publication_name nvarchar(512)
  10408.     
  10409.     /* 
  10410.     ** Initialization
  10411.     */
  10412.     SELECT @expanded = 0
  10413.     SELECT @drop_null_pub = 0
  10414.     SELECT @push = 0
  10415.  
  10416.     /*
  10417.     ** Get the original set value off IMPLICIT_TRANSACTIONS and CURSOR_CLOSE_ON_COMMIT
  10418.     **      before set these two to off
  10419.     */
  10420.     select @implicit_transaction = 0
  10421.     select @close_cursor_at_commit = 0
  10422.     IF (@reserved = 0)
  10423.     BEGIN
  10424.         SELECT @implicit_transaction = @@options & 2
  10425.         SELECT @close_cursor_at_commit = @@options & 4
  10426.         SET IMPLICIT_TRANSACTIONS OFF
  10427.         SET CURSOR_CLOSE_ON_COMMIT OFF
  10428.     END
  10429.  
  10430.     /*
  10431.     ** Security Check
  10432.     */
  10433.  
  10434.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  10435.     IF @@ERROR <> 0 or @retcode <> 0
  10436.         RETURN(1)
  10437.  
  10438.     SELECT @drop_push_bit = 0    
  10439.     
  10440.     /*
  10441.     ** Check parameter and set expressions used by cursor
  10442.     */
  10443.     
  10444.     /* Publisher */
  10445.     IF @publisher IS NULL
  10446.     BEGIN
  10447.         RAISERROR (14043, 16, -1, '@publisher')
  10448.         RETURN (1)
  10449.     END
  10450.  
  10451.     IF @publisher = 'all'
  10452.     BEGIN
  10453.         SELECT @publisher_ex = '%'
  10454.         SELECT @expanded = 1
  10455.     END
  10456.     ELSE
  10457.     BEGIN
  10458.         EXECUTE @retcode = dbo.sp_validname @publisher
  10459.         IF @retcode <> 0
  10460.         RETURN (1)
  10461.         SELECT @publisher_ex = @publisher
  10462.     END
  10463.  
  10464.  
  10465.     /* Publisher_db */
  10466.     IF @publisher_db IS NULL
  10467.     BEGIN
  10468.             RAISERROR (14043, 16, -1, '@publisher_db')
  10469.             RETURN (1)
  10470.     END
  10471.  
  10472.     IF @publisher_db = 'all'
  10473.     BEGIN
  10474.         SELECT @publisher_db_ex = '%'
  10475.         select @expanded = 1
  10476.     END
  10477.     ELSE
  10478.     BEGIN
  10479.         /*
  10480.         EXECUTE @retcode = dbo.sp_validname @publisher_db
  10481.         IF @retcode <> 0
  10482.         RETURN (1)
  10483.         */
  10484.         SELECT @publisher_db_ex = @publisher_db
  10485.     END
  10486.  
  10487.     /* 
  10488.     ** Publication
  10489.     ** '' is not a valid name but it may be in the publication name in the table. 
  10490.     */
  10491.     IF @publication IS NULL OR @publication = ''
  10492.     BEGIN
  10493.         SELECT @drop_null_pub = 1
  10494.     END
  10495.     ELSE IF @publication = 'all'
  10496.     BEGIN
  10497.         SELECT @publication_ex = '%'
  10498.         SELECT @expanded = 1
  10499.         SELECT @drop_null_pub = 1
  10500.     END
  10501.     ELSE
  10502.     BEGIN
  10503.         EXECUTE @retcode = dbo.sp_validname @publication
  10504.         IF @retcode <> 0
  10505.         RETURN (1)
  10506.         SELECT @publication_ex = @publication
  10507.     END
  10508.  
  10509.     /*
  10510.     ** Check to see if the  subscription table exists
  10511.     */
  10512.     IF NOT EXISTS (SELECT * FROM sysobjects 
  10513.                 WHERE type = 'U' AND
  10514.                       name = 'MSreplication_subscriptions')
  10515.     BEGIN
  10516.         IF @expanded = 0
  10517.         BEGIN
  10518.             RAISERROR(14135, 11, -1,  @publisher, 
  10519.                 @publisher_db, @publication)
  10520.             RETURN(1)
  10521.         END
  10522.         ELSE
  10523.             RETURN(0)
  10524.     END
  10525.  
  10526.     IF @expanded = 0 
  10527.     BEGIN 
  10528.         /*
  10529.         **
  10530.         ** Check to see if the subscription entry exists
  10531.         */
  10532.         IF  NOT EXISTS (SELECT * FROM  MSreplication_subscriptions 
  10533.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  10534.                       publisher_db = @publisher_db AND
  10535.                       publication = @publication)     
  10536.         BEGIN
  10537.             RAISERROR(14135, 11, -1, @publisher, @publisher_db, @publication)
  10538.             RETURN(1)
  10539.         END
  10540.  
  10541.         /* 
  10542.         ** Make sure the subscription is not push type if @drop_push_bit = 0
  10543.         */
  10544.         IF @drop_push_bit = 0
  10545.         BEGIN
  10546.             IF EXISTS (SELECT * FROM MSreplication_subscriptions 
  10547.                 WHERE UPPER(publisher) = UPPER(@publisher) AND
  10548.                   publisher_db = @publisher_db AND
  10549.                   publication = @publication AND
  10550.                   subscription_type = @push AND
  10551.                   @drop_push_bit = 0)
  10552.             BEGIN
  10553.                 RAISERROR(20017, 16, -1)
  10554.                 RETURN(1)
  10555.             END
  10556.         END
  10557.  
  10558.     END
  10559.     ELSE
  10560.     /* 
  10561.     ** Open a cursor and call recursively if
  10562.     ** parameters are expanded.
  10563.     */
  10564.     BEGIN
  10565.  
  10566.         /*        
  10567.         **  Note: Any expression check on null value is false
  10568.         ** @subscription_type_id is NULL <==> push
  10569.         ** @subscription_type_id is NOT NULL <==> non push
  10570.         */
  10571.         -- Have to use static cursor option because 
  10572.         DECLARE hCdroppullsubscription CURSOR STATIC LOCAL FORWARD_ONLY FOR
  10573.             SELECT DISTINCT publisher, publisher_db, publication    
  10574.                 FROM MSreplication_subscriptions
  10575.                 WHERE ((@publisher_ex = N'%') OR (UPPER(publisher) = UPPER(@publisher_ex))) AND
  10576.                                           ((@publisher_db_ex = N'%') OR ( publisher_db = @publisher_db_ex)) AND
  10577.                       (publication LIKE @publication_ex OR
  10578.                       (@drop_null_pub = 1 AND
  10579.                       publication IS NULL)) AND
  10580.                       ((@drop_push_bit =0 AND
  10581.                       subscription_type <> @push) OR
  10582.                       @drop_push_bit = 1)
  10583.         FOR READ ONLY
  10584.         OPEN hCdroppullsubscription
  10585.  
  10586.         FETCH hCdroppullsubscription INTO @publisher, 
  10587.             @publisher_db, @publication
  10588.         WHILE (@@fetch_status <> -1)
  10589.         BEGIN
  10590.             EXECUTE @retcode  = dbo.sp_droppullsubscription @publisher = @publisher, 
  10591.                 @publisher_db = @publisher_db, @publication = @publication, 
  10592.                 @reserved = 1
  10593.  
  10594.             FETCH hCdroppullsubscription INTO @publisher, 
  10595.                 @publisher_db, @publication
  10596.         END
  10597.  
  10598.         CLOSE hCdroppullsubscription
  10599.         DEALLOCATE hCdroppullsubscription
  10600.         RETURN (0)
  10601.     END
  10602.     
  10603.     /*
  10604.     ** Only members of the sysadmin group and the creator of the distribution
  10605.     ** agent can drop a pull subscription successfully. This behavior matches 
  10606.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  10607.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  10608.     ** is null.
  10609.     */
  10610.  
  10611.     EXEC sp_MSget_pullsubsagent_owner @publisher = @publisher,
  10612.                                       @publisher_db = @publisher_db,
  10613.                                       @publication = @publication,
  10614.                                       @owner_sid = @owner_sid OUTPUT
  10615.  
  10616.     IF (@owner_sid is not null AND
  10617.         (SUSER_SID() <> @owner_sid) AND
  10618.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  10619.     BEGIN
  10620.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  10621.         SELECT @qualified_publication_name = @publisher + N':' + 
  10622.                                              @publisher_db + N':' +
  10623.                                              @publication
  10624.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  10625.         RETURN (1)
  10626.     END
  10627.  
  10628.     /* 
  10629.     ** Get the agent name, it may be dropped later.
  10630.     */
  10631.     SELECT @agent_id = agent_id FROM MSreplication_subscriptions
  10632.                     WHERE UPPER(publisher) = UPPER(@publisher) AND
  10633.                           publisher_db  = @publisher_db AND
  10634.                           publication = @publication 
  10635.  
  10636.     -- If the agent is used by other subscription, don't drop it.
  10637.     if (select count(*) from MSreplication_subscriptions where
  10638.         agent_id = @agent_id) > 1
  10639.         select @agent_id = NULL
  10640.  
  10641.     begin tran
  10642.     save TRAN droppullsubscription
  10643.  
  10644.     /*
  10645.     ** Drop the subscription entry and the distribution agent if it exists 
  10646.     */
  10647.  
  10648.  
  10649.     /* 
  10650.     ** If the distribution agent is not used anymore,
  10651.     ** drop the agent if it exists
  10652.     */
  10653.  
  10654.     IF @agent_id IS NOT NULL
  10655.     BEGIN
  10656.         IF (EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @agent_id))
  10657.         BEGIN
  10658.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @agent_id
  10659.              IF @@ERROR <> 0 or @retcode <> 0
  10660.                 GOTO UNDO
  10661.  
  10662.             -- Delete MSreplication_subsciptions table after dropping 
  10663.             -- the distribution agent and delay one second
  10664.             -- to avoid deadlock with it.
  10665.             WAITFOR DELAY '00:00:01'
  10666.         END
  10667.  
  10668.     END
  10669.  
  10670.     /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  10671.     declare @subscriber_db sysname
  10672.     set @subscriber_db = DB_NAME()
  10673.     exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  10674.                                 @publisher_db = @publisher_db,
  10675.                                 @publication = @publication,
  10676.                                 @subscriber = @@SERVERNAME,
  10677.                                 @subscriber_db = @subscriber_db
  10678.  
  10679.     IF @retcode<>0 or @@ERROR<>0
  10680.         GOTO UNDO
  10681.     /*
  10682.     -- Delete MSreplication_subsciptions table after dropping the distribution agent\
  10683.     -- To avoid deadlock with it.
  10684.     --DELETE MSreplication_subscriptions WHERE UPPER(publisher) = UPPER(@publisher)    AND
  10685.         --publisher_db  = @publisher_db AND
  10686.         --publication = @publication 
  10687.     
  10688.     --IF @@ERROR <> 0 
  10689.     --    GOTO UNDO
  10690.  
  10691.     */
  10692.     
  10693.     IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  10694.     BEGIN
  10695.         DELETE FROM MSsubscription_properties 
  10696.         WHERE UPPER(publisher) = UPPER(@publisher)    AND
  10697.         publisher_db  = @publisher_db AND
  10698.         publication = @publication 
  10699.  
  10700.         IF @@ERROR <> 0 
  10701.             GOTO UNDO
  10702.  
  10703.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  10704.         BEGIN
  10705.             exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  10706.             IF @@ERROR <> 0 or @retcode <> 0
  10707.                 GOTO UNDO
  10708.         END
  10709.     END
  10710.     
  10711.     /*
  10712.     ** Clean up metadata at subscriber side
  10713.     */
  10714.     -- Note: sp_subscription_cleanup should be called after deleting the row
  10715.     -- in MSreplication_subscriptions.
  10716.     exec @retcode = dbo.sp_subscription_cleanup @publisher = @publisher,
  10717.                                             @publisher_db  = @publisher_db,
  10718.                                             @publication = @publication
  10719.     IF @retcode<>0 or @@ERROR<>0
  10720.         GOTO UNDO
  10721.  
  10722.     --
  10723.     -- drop table MSreplication_subscriptions if empty and
  10724.     -- not in recursive call
  10725.     --
  10726.     IF EXISTS (SELECT * 
  10727.                  FROM sysobjects 
  10728.                 WHERE name = 'MSreplication_subscriptions' 
  10729.                   AND type = 'U')
  10730.     BEGIN
  10731.         IF (@reserved = 0 AND 
  10732.             NOT EXISTS (SELECT * FROM MSreplication_subscriptions))
  10733.         BEGIN
  10734.             DROP TABLE MSreplication_subscriptions
  10735.             IF @@ERROR <> 0 
  10736.                 GOTO UNDO
  10737.         END
  10738.     END
  10739.  
  10740.     COMMIT TRAN
  10741.     /*
  10742.     ** set back the two settings if needed 
  10743.     */
  10744.     if @reserved = 0
  10745.     BEGIN
  10746.         IF @implicit_transaction <>0 
  10747.             SET IMPLICIT_TRANSACTIONS ON
  10748.         IF @close_cursor_at_commit <>0 
  10749.             SET CURSOR_CLOSE_ON_COMMIT ON
  10750.     END
  10751.     RETURN (0)
  10752.  
  10753. UNDO:
  10754.     IF @@TRANCOUNT > 0
  10755.     begin
  10756.         ROLLBACK TRAN droppullsubscription
  10757.         COMMIT TRAN   
  10758.     end
  10759.     /*
  10760.     ** set back the two settings if needed
  10761.     */
  10762.     if @reserved = 0
  10763.     BEGIN
  10764.         IF @implicit_transaction <>0 
  10765.             SET IMPLICIT_TRANSACTIONS ON
  10766.         IF @close_cursor_at_commit <>0 
  10767.             SET CURSOR_CLOSE_ON_COMMIT ON
  10768.     END
  10769.  
  10770.     return 1
  10771. go
  10772.  
  10773.  
  10774. raiserror('Creating procedure sp_helppullsubscription', 0,1, 0,1)
  10775. go
  10776.  
  10777. CREATE PROCEDURE sp_helppullsubscription (
  10778.     @publisher sysname = '%',
  10779.     @publisher_db sysname = '%',
  10780.     @publication sysname = '%',
  10781.     @show_push nvarchar(5) = 'false'
  10782.     ) AS
  10783.  
  10784.     SET NOCOUNT ON
  10785.  
  10786.     /*
  10787.     ** Declarations.
  10788.     */
  10789.  
  10790.  
  10791.     DECLARE @command nvarchar(255)
  10792.     DECLARE @name nvarchar(255)
  10793.     DECLARE @retcode int
  10794.     DECLARE @show_push_bit bit
  10795.     DECLARE @push int
  10796.     declare @subscriber            sysname
  10797.     declare @subscriber_db        sysname
  10798.     declare @publisher_local    sysname
  10799.     declare @publisher_db_local    sysname
  10800.     declare @publication_local    sysname
  10801.     declare @subscription_name     nvarchar(1000)
  10802.     declare @regkey                nvarchar(1000)
  10803.     declare @syncmgr_keyexist                int
  10804.     declare @helpsubscriptioncursor_open    int
  10805.  
  10806.  
  10807.     SELECT @push = 0
  10808.  
  10809.     -- For attach
  10810.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  10811.         -- The database is attached from a subscription copy file without using
  10812.         -- sp_attachsubscription. Return nothing
  10813.         return 0
  10814.  
  10815.     /*
  10816.     ** Security Check
  10817.     */
  10818.  
  10819.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  10820.     IF @@ERROR <> 0 or @retcode <> 0
  10821.         RETURN(1)
  10822.  
  10823.     /*
  10824.     ** Initializations.
  10825.     */
  10826.     set @subscriber = @@SERVERNAME     
  10827.     set @subscriber_db = DB_NAME()
  10828.  
  10829.     /*
  10830.     ** Parameter Check: @publisher
  10831.     ** Check to make sure that the publisher is define
  10832.     */
  10833.     IF @publisher IS NULL
  10834.     BEGIN
  10835.         RAISERROR (14043, 16, -1, '@publisher')
  10836.         RETURN (1)
  10837.     END
  10838.  
  10839.     IF @publisher <> '%' 
  10840.     BEGIN
  10841.         EXECUTE @retcode = dbo.sp_validname @publisher
  10842.  
  10843.         IF @@ERROR <> 0 OR @retcode <> 0
  10844.                RETURN (1)
  10845.     END
  10846.  
  10847.     IF @publication <> '%' 
  10848.     BEGIN
  10849.         EXECUTE @retcode = dbo.sp_validname @publication
  10850.  
  10851.         IF @@ERROR <> 0 OR @retcode <> 0
  10852.                RETURN (1)
  10853.     END
  10854.  
  10855.  
  10856.     IF @show_push IS NOT NULL AND 
  10857.         LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  10858.     BEGIN
  10859.         RAISERROR (14148, 16, -1, '@show_push')
  10860.         RETURN (1)
  10861.     END
  10862.  
  10863.     IF LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) = 'false'                
  10864.         SELECT @show_push_bit = 0    
  10865.     IF LOWER(@show_push collate SQL_Latin1_General_CP1_CS_AS) = 'true'    
  10866.         SELECT @show_push_bit = 1
  10867.  
  10868.  
  10869.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  10870.         type = 'U' AND
  10871.         name = 'MSreplication_subscriptions')
  10872.         RETURN (0)
  10873.  
  10874.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  10875.         type = 'U' AND
  10876.         name = 'MSsubscription_properties')
  10877.         RETURN (0)
  10878.  
  10879.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  10880.         type = 'U' AND
  10881.         name = 'MSsubscription_agents')
  10882.         RETURN (0)
  10883.  
  10884.                 
  10885.     /*
  10886.     ** Get the result
  10887.     **
  10888.     ** Note: have to return meta data
  10889.     */
  10890.         SELECT  'publisher'                = rs.publisher,
  10891.             'publisher database'    = rs.publisher_db,
  10892.             'publication'            = rs.publication,
  10893.             'independent_agent'        = rs.independent_agent,
  10894.             'subscription type'     = rs.subscription_type,
  10895.             'distribution agent'    = distribution_agent,
  10896.             'publication description'   = description,
  10897.             'last updating time'        = convert(nvarchar(12), time, 112) + 
  10898.                                           substring(convert(nvarchar(24), time, 121), 11,13),
  10899.             'subscription_name'          = rs.publisher + ':' + rs.publisher_db + ':' + rs.publication,
  10900.             'last transaction timestamp' = transaction_timestamp,
  10901.             -- SyncTran
  10902.             -- For Queued case, we will return 2/3 for values 4/5 so that
  10903.             -- SQL-DMO does not have to deal with the overloaded values of update_mode
  10904.             'update_mode'         = case     when rs.update_mode = 4 then 2
  10905.                                             when rs.update_mode = 5 then 3
  10906.                                             else rs.update_mode
  10907.                                     end,
  10908.             'distribution agent job_id' = agent_id,
  10909.             'enabled for syncmgr' = enabled_for_syncmgr,
  10910.             'subscription guid' = subscription_guid,
  10911.             'subid ' = subid,
  10912.             'immediate_sync' = immediate_sync,
  10913.             'publisher_login' = publisher_login,
  10914.             'publisher_password' = publisher_password,
  10915.             'publisher_security_mode' = publisher_security_mode,
  10916.             'distributor' = distributor,
  10917.             'distributor_login' = distributor_login,
  10918.             'distributor_password' = distributor_password,
  10919.             'distributor_security_mode' = distributor_security_mode,
  10920.             'ftp_address' = ftp_address,
  10921.             'ftp_port' = ftp_port,
  10922.             'ftp_login' = ftp_login,
  10923.             'ftp_password' = ftp_password,
  10924.             'alt_snapshot_folder' = alt_snapshot_folder,
  10925.             'working_directory' = working_directory,
  10926.             'use_ftp' = use_ftp,
  10927.             'publication_type' = publication_type,
  10928.             'dts_package_name' = dts_package_name,
  10929.             'dts_package_location' = dts_package_location,
  10930.             'offload_agent' = offload_agent,
  10931.             'offload_server' = offload_server,
  10932.             a.last_sync_status, 
  10933.             a.last_sync_summary,
  10934.             'last_sync_time' = convert(nvarchar(12), a.last_sync_time, 112) + 
  10935.                 substring(convert(nvarchar(24), a.last_sync_time, 121), 11,13)
  10936.        from MSreplication_subscriptions rs
  10937.        left outer join MSsubscription_properties sp 
  10938.                     on (UPPER(rs.publisher) = UPPER(sp.publisher) and rs.publisher_db = sp.publisher_db and rs.publication = sp.publication) 
  10939.        left outer join MSsubscription_agents a
  10940.                     on (UPPER(rs.publisher) = UPPER(a.publisher) and 
  10941.                         rs.publisher_db = a.publisher_db and 
  10942.                         ((rs.publication = a.publication and 
  10943.                         rs.independent_agent = 1 and
  10944.                         a.publication <> N'ALL') or
  10945.                         (a.publication = N'ALL' and rs.independent_agent = 0)) and
  10946.                         rs.subscription_type = a.subscription_type)
  10947.                 where ((@publisher = N'%') OR (UPPER(rs.publisher) = UPPER(@publisher))) AND
  10948.                       ((@publisher_db = N'%') OR (rs.publisher_db = @publisher_db)) AND
  10949.                       ((@publication = N'ALL' AND rs.independent_agent = 0) OR rs.publication LIKE @publication) AND
  10950.                       (rs.subscription_type <> @push OR
  10951.                        @show_push_bit = 1)
  10952.         ORDER BY rs.publisher, rs.publisher_db, rs.publication  
  10953. GO
  10954.  
  10955.  
  10956. raiserror('Creating procedure sp_MStable_has_unique_index', 0,1)
  10957. go
  10958.  
  10959. create procedure sp_MStable_has_unique_index @tabid int
  10960. as
  10961. begin
  10962.  
  10963.     /* 
  10964.     ** Returns id of unique index, if it exists, else 0
  10965.     */
  10966.     declare @indid int
  10967.  
  10968.     if (ObjectProperty(@tabid, 'IsTable') = 1) and (ObjectProperty(@tabid, 'TableHasIndex') = 1)
  10969.     begin
  10970.         -- First get the primary index id. 
  10971.         select @indid = i.indid from sysindexes i where 
  10972.             -- get the primary key index
  10973.             (i.status & 2048) <> 0
  10974.             and i.id = @tabid
  10975.  
  10976.         if @indid is null
  10977.         begin
  10978.             -- Get the first unique index
  10979.             select top 1 @indid = i.indid from sysindexes i where 
  10980.                 (i.status & 2) <> 0
  10981.                 and i.id = @tabid
  10982.                 order by i.indid asc
  10983.         end
  10984.         if @indid is null select @indid = 0
  10985.     end
  10986.     else
  10987.         select @indid = 0
  10988.  
  10989.     return @indid
  10990. end
  10991. go
  10992.  
  10993. raiserror('Creating procedure sp_MSchange_retention', 0,1)
  10994. GO
  10995.  
  10996. CREATE PROCEDURE sp_MSchange_retention (@pubid uniqueidentifier, @value nvarchar(255))
  10997. as
  10998.     declare @re_pubid            uniqueidentifier 
  10999.     declare @artid                uniqueidentifier
  11000.     declare @schemaversion      int 
  11001.     declare @schemaguid         uniqueidentifier
  11002.     declare @schematype         int
  11003.     declare @schematext         nvarchar(2000)
  11004.     declare @retcode            int
  11005.     begin TRAN    
  11006.         update sysmergepublications set retention = convert(int, @value) where pubid = @pubid
  11007.         if @@ERROR<>0
  11008.             goto UNDO
  11009.             
  11010.         declare #change_retention CURSOR LOCAL FAST_FORWARD fast_forward for 
  11011.             select pubid from sysmergearticles where pubid<>@pubid and nickname in
  11012.                 (select nickname from sysmergearticles where pubid=@pubid)
  11013.         open #change_retention
  11014.         fetch #change_retention into @re_pubid
  11015.         while (@@fetch_status <> -1)
  11016.         BEGIN
  11017.             update sysmergepublications set retention = convert(int, @value) where pubid = @re_pubid
  11018.             if @@ERROR<>0
  11019.                 goto UNDO
  11020.             set @schematype = 9 /* change retention */
  11021.             set @artid = newid()
  11022.             select @schematext = 'exec dbo.sp_MSchange_retention '+ '''' + convert(nchar(36),@re_pubid) + '''' + ',' + '''' + @value + ''''          
  11023.             select @schemaversion = schemaversion from sysmergeschemachange
  11024.             if (@schemaversion is NULL)
  11025.                 set @schemaversion = 1
  11026.             else
  11027.                 select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  11028.             set @schemaguid = newid()
  11029.             exec @retcode=sp_MSinsertschemachange @re_pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  11030.             if @@ERROR<>0 or @retcode<>0 
  11031.                 goto UNDO
  11032.             fetch #change_retention into @re_pubid
  11033.         END
  11034.         close #change_retention
  11035.         deallocate #change_retention
  11036.     COMMIT TRAN
  11037.     return (0)
  11038. UNDO:
  11039.     if @@TRANCOUNT = 1
  11040.         ROLLBACK TRAN
  11041.     else
  11042.         COMMIT TRAN
  11043.     return(1)
  11044. GO
  11045. exec dbo.sp_MS_marksystemobject sp_MSchange_retention 
  11046. go
  11047. grant execute on dbo.sp_MSchange_retention to public
  11048.  
  11049.  
  11050. raiserror('Creating procedure sp_MSchange_priority', 0,1)
  11051. GO
  11052. -- @value has to be unicode too.
  11053.  
  11054. CREATE PROCEDURE sp_MSchange_priority (@subid uniqueidentifier, @value nvarchar(255))
  11055. as
  11056.     update sysmergesubscriptions set priority = convert(real, @value)
  11057.            where subid = @subid
  11058. go
  11059. exec dbo.sp_MS_marksystemobject sp_MSchange_priority 
  11060. go
  11061. grant execute on dbo.sp_MSchange_priority to public
  11062.  
  11063. raiserror('Creating procedure sp_expired_subscription_cleanup', 0,1)
  11064. GO
  11065.  
  11066. CREATE PROCEDURE sp_expired_subscription_cleanup
  11067. AS
  11068. declare @retcode         int
  11069. declare @publisher_db    sysname
  11070. declare @category        int
  11071. declare @proc_name        nvarchar(200)
  11072. declare @distributor     sysname
  11073. declare @distribdb        sysname
  11074. declare @distproc        nvarchar(300)
  11075. /*
  11076. ** Security Check
  11077. */
  11078.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  11079.     IF @@ERROR <> 0 or @retcode <> 0
  11080.         return (1)
  11081.     /*
  11082.     ** Get distribution server information for remote RPC call.
  11083.     */
  11084.  
  11085. EXECUTE @retcode = sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  11086.      @distribdb   = @distribdb OUTPUT
  11087. IF @@ERROR <> 0 or @retcode <> 0
  11088.     BEGIN
  11089.         RAISERROR (20036, 16, -1)
  11090.         return (1)
  11091.     END
  11092.     
  11093.         
  11094. DECLARE DC CURSOR LOCAL FAST_FORWARD for select DISTINCT name, category from master..sysdatabases 
  11095.     where (category & 4) = 4 or (category & 1 = 1)
  11096.     for read only
  11097.     open DC
  11098.     fetch DC into @publisher_db, @category
  11099.     WHILE (@@fetch_status <> -1)
  11100.     BEGIN
  11101.         if (@category & 4 = 4)
  11102.             begin
  11103.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_mergesubscription'
  11104.                 exec @retcode = @proc_name
  11105.                 if @retcode<>0 or @@ERROR<>0
  11106.                     goto DONE
  11107.             end
  11108.         if (@category & 1 = 1)
  11109.             begin
  11110.                 select @proc_name = @publisher_db + '.dbo.sp_MSdrop_expired_subscription'
  11111.                 exec @retcode = @proc_name
  11112.                 if @retcode<>0 or @@ERROR<>0
  11113.                     goto DONE
  11114.             end    
  11115.     fetch DC into @publisher_db, @category
  11116.     END
  11117.  
  11118.     /*
  11119.     ** sp_MScleanup_agent_entry in distribution database is called to periodically remove obselete
  11120.     ** entries in MSmerge_agents, which may be caused by the following reasons:
  11121.     **  1. publishing database is externally removed; therefore cleanup agent can not do its job
  11122.     **  2. Entries for anonymous merge subscriptions
  11123.     */
  11124.     SELECT @distproc = RTRIM(@distributor) + '.' + RTRIM(@distribdb) + '..sp_MScleanup_agent_entry'
  11125.     exec @retcode = @distproc 
  11126.     if @@ERROR<>0 or @retcode<>0
  11127.     BEGIN
  11128.         close DC
  11129.         deallocate DC
  11130.         return (1)
  11131.     END
  11132.  
  11133. DONE:
  11134.     close DC
  11135.     deallocate DC
  11136. GO
  11137.  
  11138. go
  11139. exec dbo.sp_MS_marksystemobject sp_expired_subscription_cleanup
  11140. go
  11141. grant execute on dbo.sp_expired_subscription_cleanup to public
  11142.  
  11143.  
  11144. raiserror('Creating procedure sp_addmergepullsubscription', 0,1)
  11145. GO
  11146.  
  11147. CREATE PROCEDURE sp_addmergepullsubscription (
  11148.     @publication                 sysname,                      /* Publication name */
  11149.     @publisher                    sysname = @@SERVERNAME,      /* Publisher server */
  11150.     @publisher_db                sysname = NULL,              /* Publication database */
  11151.     @subscriber_type             nvarchar(15) = 'local',            /* Subscriber type */ 
  11152.     @subscription_priority         real         = NULL,                /* Subscription priority */
  11153.     @sync_type                     nvarchar(15) = 'automatic', /* subscription sync type */
  11154.     @description                 nvarchar(255) = NULL              
  11155.      ) AS
  11156.  
  11157.     SET NOCOUNT ON
  11158.  
  11159.     /*
  11160.     ** Declarations.
  11161.     */
  11162.     declare @retcode                int
  11163.     declare    @subscriber_db            sysname
  11164.     declare @subnickname            int
  11165.     declare @subscriber_srvid        int 
  11166.     declare @publisher_srvid        int 
  11167.     declare @priority                 real
  11168.     declare @subid                     uniqueidentifier
  11169.     declare @subscriber_typeid         smallint
  11170.     declare @subscription_type         smallint
  11171.     declare @command                 nvarchar(255)
  11172.     declare @inactive                tinyint 
  11173.     declare @global                 tinyint        /* subscriber type is global */
  11174.     declare @push                     tinyint        /* subscription type is push */
  11175.      
  11176.     declare @sync_typeid             tinyint
  11177.     declare @nosync                 tinyint        
  11178.     declare @automatic                tinyint             
  11179.     declare @pubid                    uniqueidentifier             
  11180.     declare @partnerid                uniqueidentifier             
  11181.     declare @parentid               uniqueidentifier
  11182.  
  11183.     /*
  11184.     ** Initializations.
  11185.     */
  11186.  
  11187.     SET @nosync             = 2       /* Const: synchronization type 'none' */
  11188.     SET @automatic             = 1       /* Const: synchronization type 'automatic' */
  11189.     SET @inactive             = 0
  11190.     SET @global             = 1
  11191.     SET @push                 = 0   
  11192.  
  11193.  
  11194.     set @pubid                 = newid()
  11195.     set @partnerid            = @pubid
  11196.     
  11197.     set @parentid            = '00000000-0000-0000-0000-000000000000'
  11198.      
  11199.     /* 
  11200.     ** Check if replication components are installed on this server
  11201.     */
  11202.     exec @retcode = dbo.sp_MS_replication_installed
  11203.     if (@retcode <> 1)
  11204.     begin
  11205.         return (1)
  11206.     end
  11207.  
  11208.     /*
  11209.     ** Security Check.
  11210.     */
  11211.  
  11212.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  11213.     if @@ERROR <> 0 or @retcode <> 0
  11214.         return(1)
  11215.  
  11216.     /*
  11217.     **    Check to see if merge system tables exist. Create them unless they already
  11218.     **  exist.
  11219.     */
  11220.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  11221.         BEGIN
  11222.             execute @retcode = dbo.sp_MScreate_mergesystables
  11223.                 if @@ERROR <> 0 or @retcode <> 0
  11224.                     begin
  11225.                         return (1)
  11226.                     end
  11227.         END    
  11228.  
  11229.     if UPPER(@publisher) = UPPER(@@SERVERNAME) and @publisher_db = db_name()
  11230.         begin
  11231.             raiserror(21126, 16, -1)
  11232.             return (1)
  11233.         end
  11234.  
  11235.     if exists (select pubid from sysmergepublications where UPPER(publisher) = UPPER(@@SERVERNAME) and publisher_db=db_name()) and @subscriber_type in ('local', 'anonymous')
  11236.         begin
  11237.             declare @dbname sysname
  11238.             select @dbname = DB_NAME()
  11239.             raiserror(21258, 16, -1, @dbname)
  11240.             return (1)
  11241.         end
  11242.     /* 
  11243.     ** When adding a pull subscription, if a push subscription for that publication already exists, 
  11244.     ** we will raise error and fail
  11245.     */
  11246.     IF EXISTS (select name from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db)
  11247.     BEGIN
  11248.         select @pubid=pubid from sysmergepublications 
  11249.             where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  11250.         IF EXISTS (select subid from sysmergesubscriptions where pubid=@pubid and subid<>@pubid and subscription_type=0)
  11251.             begin
  11252.                 RAISERROR (21317, 16, -1, @publication)
  11253.                 return (1)
  11254.             end
  11255.         ELSE
  11256.             begin
  11257.                 IF EXISTS (select status from sysmergesubscriptions where pubid=@pubid and status =    2)
  11258.                     begin
  11259.                         select @subid = subid from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  11260.                         delete sysmergesubscriptions where pubid=@pubid
  11261.                         delete MSmerge_replinfo where repid = @subid
  11262.                     end
  11263.                 ELSE 
  11264.                     begin
  11265.                         RAISERROR (14058, 16, -1)
  11266.                         return (1)
  11267.                     end
  11268.             end
  11269.     END
  11270.  
  11271.     set @partnerid = @pubid
  11272.      
  11273.       /*
  11274.     ** Assign parameter values appropriately for the local server database
  11275.     */
  11276.     set @subscriber_db = DB_NAME()
  11277.     select @subscriber_srvid = 0
  11278.  
  11279.     /*
  11280.     ** Parameter Check: @publisher
  11281.     ** Check to make sure that the publisher is defined
  11282.     */
  11283.     IF @publisher IS NULL
  11284.     BEGIN
  11285.         RAISERROR (14043, 16, -1, '@publisher')
  11286.         RETURN (1)
  11287.     END
  11288.  
  11289.     IF LOWER(@publisher) = 'all'
  11290.     BEGIN
  11291.         RAISERROR (14136, 16, -1)
  11292.         RETURN (1)
  11293.     END
  11294.  
  11295.     EXECUTE @retcode = dbo.sp_validname @publisher
  11296.     IF @@ERROR <> 0 OR @retcode <> 0
  11297.        RETURN (1)
  11298.     /*
  11299.     ** Validate that the publisher is a valid server
  11300.     */
  11301.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  11302.     IF @publisher_srvid IS NULL
  11303.         BEGIN
  11304.             EXECUTE @retcode = dbo.sp_addserver @publisher
  11305.             IF @@error <> 0 OR @retcode <> 0
  11306.                 BEGIN
  11307.                     RAISERROR (14010, 16, -1)
  11308.                        RETURN (1)
  11309.                 END
  11310.             ELSE
  11311.                 select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  11312.         END
  11313.  
  11314.  
  11315.     /*
  11316.     ** Parameter Check: @publisher_db
  11317.     */
  11318.     IF @publisher_db IS NULL
  11319.     BEGIN
  11320.         RAISERROR (14043, 16, -1, '@publisher_db')
  11321.         RETURN (1)
  11322.     END
  11323.  
  11324.     IF LOWER(@publisher_db) = 'all'
  11325.     BEGIN
  11326.         RAISERROR (14136, 16, -1)
  11327.         RETURN (1)
  11328.     END
  11329.     
  11330.     /*
  11331.     ** Check to see if the publication name is already used in the subscription 
  11332.     ** database - This is the case where we are resubscribing to the same publication.
  11333.     ** Execute dbo.sp_MSpublicationcleanup to cleanup all all the defunct rows
  11334.     
  11335.     ** if exists (select * from sysmergepublications where name = @publication)
  11336.     ** begin
  11337.     **    exec @retcode = dbo.sp_MSpublicationcleanup 
  11338.     **    IF @@ERROR <> 0 OR @retcode <> 0
  11339.     **        BEGIN
  11340.     **            RAISERROR (20025, 16, -1, @publication)
  11341.     **            RETURN (1)
  11342.     **        END                        
  11343.     ** end
  11344.     */
  11345.  
  11346.     /*
  11347.     ** Parameter Check: @subscriber_type.
  11348.     ** Set subscriber_typeid based on the @subscriber_type specified.
  11349.     **
  11350.     **   subscriber_type     subscriber_type
  11351.     **   =================    ===============
  11352.     **             1             global
  11353.     **             2             local
  11354.     **             3             anonymous
  11355.     **             NO support for republisher for B 3
  11356.     */
  11357.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('local', 'global', 'anonymous')
  11358.         BEGIN
  11359.               RAISERROR (20023, 16, -1)
  11360.             RETURN (1)
  11361.         END
  11362.  
  11363.     set @subscription_type = 1 /* pull by default */
  11364.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('global')
  11365.         set @subscriber_typeid = 1
  11366.     else if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('local')
  11367.         set @subscriber_typeid = 2
  11368.     else if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('anonymous')       
  11369.         begin
  11370.             /* For anonymous subscribers set subscription type appropriately */
  11371.             set @subscriber_typeid = 3
  11372.             set @subscription_type = 2
  11373.         end            
  11374.  
  11375.     /* 
  11376.     ** Assign priority appropriately - choose 0.99 times the minimum priority
  11377.     ** of the global replicas.
  11378.     */
  11379.     if (@subscription_priority > 100.0 or @subscription_priority < 0.0)
  11380.         set @subscription_priority = NULL        
  11381.     if (@subscription_priority IS NULL)
  11382.         begin
  11383.             select @priority = 0.99 * min(priority) from sysmergesubscriptions where subscriber_type  = 1 /* global/loopback */
  11384.             if (@priority IS NOT NULL)
  11385.                 select @subscription_priority = @priority
  11386.             if (@subscription_priority IS NULL) 
  11387.                 select @subscription_priority = 0.0
  11388.         end
  11389.     /*
  11390.     ** For local and anonymous subscriptions the priority is 0.0
  11391.     */
  11392.     if LOWER(@subscriber_type collate SQL_Latin1_General_CP1_CS_AS) IN ('local', 'anonymous')
  11393.         select @subscription_priority = 0.0
  11394.  
  11395.     /*
  11396.      ** If the subscription already exists, don't add it.
  11397.     
  11398.      ** if EXISTS (select db_name, srvid
  11399.      **        FROM sysmergesubscriptions
  11400.     **         WHERE db_name = @subscriber_db
  11401.     **         AND srvid = @subscriber_srvid                           
  11402.     **        AND pubid = @pubid)
  11403.     **    BEGIN
  11404.     **        RAISERROR (14058, 16, -1)
  11405.     **        RETURN (1)
  11406.      **    END
  11407.     */
  11408.  
  11409.    /*
  11410.    ** Parameter Check: @sync_type.
  11411.    ** Set sync_typeid based on the @sync_type specified.
  11412.    **
  11413.    **   sync_typeid     sync_type
  11414.    **   ===========     =========
  11415.    **             1     automatic
  11416.    **             2     none
  11417.    */
  11418.  
  11419.  
  11420.    IF LOWER(@sync_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('automatic', 'none')
  11421.        BEGIN
  11422.            RAISERROR (14052, 16, -1)
  11423.            RETURN (1)
  11424.        END
  11425.  
  11426.  
  11427.    IF LOWER(@sync_type collate SQL_Latin1_General_CP1_CS_AS) = 'automatic'
  11428.    BEGIN
  11429.         SET @sync_typeid = @automatic
  11430.    END
  11431.    ELSE
  11432.    BEGIN
  11433.         SET @sync_typeid = @nosync
  11434.    END
  11435.  
  11436.  
  11437.     /*
  11438.     ** UNDONE: Validate that the publisher is of type 'republisher'
  11439.     */
  11440.  
  11441.     begin tran
  11442.     save TRAN addmergepullsubscription
  11443.         
  11444.         /* Generate a guid for the Subscriber ID */
  11445.         set @subid = newid()
  11446.  
  11447.         /* Look for existing nickname from any other subscription */
  11448.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  11449.         if (@@error <> 0) 
  11450.             begin
  11451.             goto FAILURE
  11452.             end                 
  11453.  
  11454.  
  11455.         /* Generate a new replica nickname from the @subid */
  11456.         if (@subnickname is null)
  11457.             EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  11458.  
  11459.     
  11460.         /* 
  11461.         ** Check to see if MSsubscription_properties table exists.
  11462.         ** If not, create it.
  11463.         */
  11464.         exec @retcode = dbo.sp_MScreate_sub_tables
  11465.             @tran_sub_table = 0,
  11466.             @property_table = 1,
  11467.             @sqlqueue_table = 0
  11468.  
  11469.         IF @@ERROR <> 0 or @retcode <> 0
  11470.             goto FAILURE
  11471.  
  11472.         /*
  11473.         ** The subscription doesn't exist, so let's add it to sysmergesubscriptions 
  11474.         */
  11475.         INSERT sysmergesubscriptions (subid, partnerid, datasource_type, srvid, db_name, 
  11476.                 pubid, status, subscriber_type, subscription_type, priority, sync_type, 
  11477.                 description, login_name, subscriber_server, publication)
  11478.                     VALUES (@subid,
  11479.                             @partnerid,
  11480.                             0,
  11481.                             @subscriber_srvid,
  11482.                             @subscriber_db,
  11483.                             @pubid,
  11484.                             @inactive,
  11485.                             @subscriber_typeid,
  11486.                             @subscription_type,     /* for a pull/anon subscription */
  11487.                             @subscription_priority,
  11488.                             @sync_typeid,
  11489.                             @description,
  11490.                             suser_sname(suser_sid()),
  11491.                             @@servername,
  11492.                             @publication)            
  11493.         if @@ERROR <> 0
  11494.             BEGIN
  11495.                 GOTO FAILURE
  11496.             END
  11497.  
  11498.         /* Add a self-subscribed subscription to represent the publication */
  11499.             
  11500.         insert sysmergepublications(publisher, publisher_db, pubid, name, parentid) 
  11501.             values(@publisher, @publisher_db, @pubid, @publication, @parentid)
  11502.         if @@ERROR <> 0
  11503.             begin
  11504.                 goto FAILURE
  11505.             end
  11506.         insert sysmergesubscriptions(subid, partnerid, datasource_type, srvid, db_name, 
  11507.                 pubid, subscriber_type, subscription_type, status, priority, sync_type, description, login_name, subscriber_server, publication, distributor)
  11508.             values (@pubid, @pubid, 0, @publisher_srvid, @publisher_db, 
  11509.                 @pubid, @global, @push, @inactive, 100.0, @sync_typeid, @description, suser_sname(suser_sid()), @publisher, @publication, @publisher)  
  11510.                         
  11511.         if @@ERROR <> 0
  11512.             begin
  11513.                 goto FAILURE
  11514.             end
  11515.                     
  11516.         /*
  11517.         **  Add row for subscription in MSmerge_replinfo.
  11518.         */
  11519.         insert MSmerge_replinfo(repid, replnickname)
  11520.                 values (@subid, @subnickname)
  11521.         if @@ERROR <> 0
  11522.             BEGIN
  11523.                 GOTO FAILURE
  11524.             END
  11525.  
  11526.     COMMIT TRAN
  11527.     return (0)
  11528.  
  11529. FAILURE:
  11530.     RAISERROR (14057, 16, -1)
  11531.     if @@trancount > 0
  11532.     begin
  11533.         ROLLBACK TRANSACTION addmergepullsubscription
  11534.         COMMIT TRANSACTION
  11535.     end
  11536.     RETURN (1)
  11537.  
  11538. go
  11539. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription 
  11540. go
  11541.  
  11542. grant execute on dbo.sp_addmergepullsubscription to public
  11543. go
  11544.  
  11545. raiserror('Creating procedure sp_changemergepullsubscription', 0,1)
  11546. GO
  11547.  
  11548. CREATE PROCEDURE sp_changemergepullsubscription (
  11549.     @publication         sysname = '%',    /* Publication name */
  11550.     @publisher            sysname = '%',  /* Publisher server */
  11551.     @publisher_db        sysname = '%',     /* Publication database */
  11552.     @property             sysname = NULL, /* The property to change */
  11553.     @value                 nvarchar(255) = NULL    /* The new property value */
  11554.     ) AS
  11555.  
  11556.     SET NOCOUNT ON
  11557.  
  11558.     /*
  11559.     ** Declarations.
  11560.     */
  11561.     declare @subscriber_srvid         int
  11562.     declare @publisher_srvid         int
  11563.     declare @retcode                 int
  11564.     declare    @pubid                     uniqueidentifier
  11565.     declare    @subid                     uniqueidentifier
  11566.     declare    @partnerid                 uniqueidentifier
  11567.     declare @sync_typeid             tinyint
  11568.     declare @nosync                 tinyint
  11569.     declare @automatic                 tinyint
  11570.      
  11571.     declare @artid                    uniqueidentifier
  11572.     declare @subscriber                sysname
  11573.     declare @subscriber_db            sysname
  11574.     declare @schematype                int
  11575.     declare @schemaversion            int
  11576.     declare @schemaguid                uniqueidentifier
  11577.     declare @db_name                sysname
  11578.     declare @subscriber_type        int
  11579.     declare @schematext                nvarchar(2000)
  11580.     declare @use_interactive_bit    bit
  11581.     declare @use_interactive_int    int
  11582.     declare @enabled_for_syncmgr    int
  11583.     declare @regkey                    nvarchar(1000)
  11584.     declare @snapshot_ready            int
  11585.     /*
  11586.     ** Initializations.
  11587.     */
  11588.     SET @subscriber     = @@SERVERNAME
  11589.     SET @subscriber_db    = DB_NAME()
  11590.     SET @nosync         = 2     /* Const: synchronization type 'none' */
  11591.     SET @automatic         = 1     /* Const: synchronization type 'automatic' */
  11592.  
  11593.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  11594.     IF @subscriber_srvid IS NULL
  11595.         BEGIN
  11596.            RAISERROR (14010, 16, -1)
  11597.            RETURN (1)     
  11598.         END
  11599.  
  11600.     /*
  11601.     ** Security Check.
  11602.     */
  11603.     BEGIN
  11604.         exec @retcode = dbo.sp_MSreplcheck_subscribe
  11605.         if @@ERROR <> 0 or @retcode <> 0
  11606.             return(1)
  11607.     END
  11608.  
  11609.  
  11610.     /*
  11611.     **    Check to see if current database is enabled for subscribing
  11612.     */
  11613.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  11614.         BEGIN
  11615.             RAISERROR (14055, 16, -1)
  11616.             RETURN (1)
  11617.         END
  11618.  
  11619.     
  11620.     /*
  11621.     ** Parameter Check:  @property.
  11622.     ** If the @property parameter is NULL, print the options.
  11623.     */
  11624.  
  11625.     IF @property IS NULL
  11626.         BEGIN
  11627.             CREATE TABLE #tab1 (properties sysname collate database_default not null)
  11628.             INSERT INTO #tab1 VALUES ('sync_type')
  11629.             INSERT INTO #tab1 VALUES ('priority')
  11630.             INSERT INTO #tab1 VALUES ('description') 
  11631.             INSERT INTO #tab1 VALUES ('use_interactive_resolver')             
  11632.             -- Properties delegated to sp_change_subscription_properties
  11633.             INSERT INTO #tab1 VALUES ('publisher_login')
  11634.             INSERT INTO #tab1 VALUES ('publisher_password')
  11635.             INSERT INTO #tab1 VALUES ('publisher_security_mode')
  11636.             INSERT INTO #tab1 VALUES ('distributor')
  11637.             INSERT INTO #tab1 VALUES ('distributor_login')
  11638.             INSERT INTO #tab1 VALUES ('distributor_password')
  11639.             INSERT INTO #tab1 VALUES ('distributor_security_mode')
  11640.             INSERT INTO #tab1 VALUES ('ftp_address')
  11641.             INSERT INTO #tab1 VALUES ('ftp_port')
  11642.             INSERT INTO #tab1 VALUES ('ftp_login')
  11643.             INSERT INTO #tab1 VALUES ('ftp_password')
  11644.             INSERT INTO #tab1 VALUES ('alt_snapshot_folder')
  11645.             INSERT INTO #tab1 VALUES ('working_directory')
  11646.             INSERT INTO #tab1 VALUES ('use_ftp')
  11647.             INSERT INTO #tab1 VALUES ('offload_agent')
  11648.             INSERT INTO #tab1 VALUES ('offload_server')
  11649.             INSERT INTO #tab1 VALUES ('dynamic_snapshot_location')
  11650.             select * FROM #tab1
  11651.             RETURN (0)
  11652.         END
  11653.  
  11654.     /*
  11655.     ** Parameter Check:  @publisher.
  11656.     ** Check to make sure we have a valid publisher.
  11657.     ** Should make sure that @publisher is non-null before using it to check whether @publication is valid
  11658.     */
  11659.     IF @publisher IS NULL
  11660.         BEGIN
  11661.             RAISERROR (14043, 16, -1, '@publisher')
  11662.             RETURN (1)
  11663.         END
  11664.  
  11665.     /*
  11666.     ** Parameter Check:  @publication.
  11667.     ** Make sure that the publication exists.
  11668.     */
  11669.  
  11670.     IF @publication IS NULL
  11671.         BEGIN
  11672.             RAISERROR (14043, 16, -1, '@publication')
  11673.             RETURN (1)
  11674.         END
  11675.  
  11676.     select @pubid = pubid FROM sysmergepublications WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  11677.     IF @pubid IS NULL
  11678.         BEGIN
  11679.             RAISERROR (20026, 11, -1, @publication)
  11680.             RETURN (1)
  11681.         END
  11682.  
  11683.     /*
  11684.     ** Validate that the publisher is a valid server
  11685.     */
  11686.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  11687.     IF @publisher_srvid IS NULL
  11688.         BEGIN
  11689.             RAISERROR (14010, 16, -1)
  11690.                RETURN (1)
  11691.         END
  11692.  
  11693.     /*
  11694.     ** Check to see if you have a local / global subscription on this publication
  11695.     */
  11696.     set @subid = NULL
  11697.     select @subid = subs1.subid, 
  11698.     @pubid = pubs.pubid, /* identified from publication name */
  11699.     @subscriber_type=subs1.subscriber_type,
  11700.         @partnerid = subs2.subid from
  11701.         sysmergesubscriptions     subs1,
  11702.           sysmergesubscriptions     subs2,
  11703.         sysmergepublications     pubs
  11704.         where subs1.srvid = @subscriber_srvid
  11705.             and subs1.db_name = @subscriber_db
  11706.             and subs2.srvid = @publisher_srvid
  11707.             and subs2.db_name = @publisher_db
  11708.             and subs1.pubid = subs2.subid
  11709.             and subs2.pubid = pubs.pubid
  11710.             and pubs.name = @publication
  11711.             and UPPER(pubs.publisher)=UPPER(@publisher)
  11712.             and pubs.publisher_db = @publisher_db
  11713.  
  11714.     if @subid IS NULL 
  11715.          begin
  11716.             RAISERROR (14050, 11, -1)
  11717.             RETURN(1)
  11718.         end                 
  11719.  
  11720.     /*
  11721.     ** Parameter Check:  @property.
  11722.     ** Check to make sure that @property is a valid property in
  11723.     ** a merge pull subscription.
  11724.     */
  11725.  
  11726.     
  11727.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) NOT IN 
  11728.                                ('sync_type', 
  11729.                                 'priority', 
  11730.                                 'description',
  11731.                                 'publisher_login',
  11732.                                 'publisher_password',
  11733.                                 'publisher_security_mode',
  11734.                                 'distributor',
  11735.                                 'distributor_login',
  11736.                                 'distributor_password',
  11737.                                 'distributor_security_mode',
  11738.                                 'ftp_address',
  11739.                                 'ftp_port',
  11740.                                 'ftp_login',
  11741.                                 'ftp_password',
  11742.                                 'alt_snapshot_folder',
  11743.                                 'working_directory',
  11744.                                 'use_ftp',
  11745.                                 'use_interactive_resolver',
  11746.                                 'offload_agent',
  11747.                                 'offload_server',
  11748.                                 'dynamic_snapshot_location')
  11749.         BEGIN
  11750.             RAISERROR (21348, 16, -1, @property)
  11751.             RETURN (1)
  11752.         END
  11753.  
  11754.     /*
  11755.     ** Change the property.
  11756.     */
  11757.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'sync_type'
  11758.         BEGIN
  11759.  
  11760.             /*
  11761.             ** Check to make sure that we have a valid sync_type.
  11762.             */
  11763.  
  11764.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('automatic', 'none')
  11765.                 BEGIN
  11766.                     RAISERROR (14052, 16, -1)
  11767.                     RETURN (1)
  11768.                 END
  11769.  
  11770.             /*
  11771.             ** Determine the integer value for the sync_type.
  11772.             */
  11773.  
  11774.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'automatic'
  11775.                 SET @sync_typeid = @automatic
  11776.             ELSE
  11777.                 SET @sync_typeid = @nosync
  11778.  
  11779.             /*
  11780.             ** Update the subscription with the new sync_type.
  11781.             */
  11782.  
  11783.             UPDATE sysmergesubscriptions
  11784.                    SET sync_type = @sync_typeid
  11785.                  WHERE subid = @subid
  11786.             IF @@ERROR <> 0
  11787.                 BEGIN
  11788.                     RAISERROR (14053, 16, -1)
  11789.                     RETURN (1)
  11790.                 END
  11791.  
  11792.         END
  11793.         
  11794.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'description'
  11795.         BEGIN
  11796.         UPDATE sysmergesubscriptions
  11797.                    SET description = @value
  11798.                  WHERE subid = @subid
  11799.             IF @@ERROR <> 0
  11800.                 BEGIN
  11801.                     RAISERROR (14053, 16, -1) 
  11802.               
  11803.                     RETURN (1)
  11804.                 END
  11805.  
  11806.         END
  11807.  
  11808.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'use_interactive_resolver'
  11809.         BEGIN
  11810.  
  11811.             /* Check to make sure that we have a true/false. */
  11812.  
  11813.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  11814.                 BEGIN
  11815.                     RAISERROR (14148, 16, -1, 'use_interactive_resolver')
  11816.                     RETURN (1)
  11817.                 END
  11818.  
  11819.             /* Determine the bit value. */
  11820.  
  11821.             IF LOWER(@value collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  11822.                 SET @use_interactive_bit = 1
  11823.             ELSE
  11824.                 SET @use_interactive_bit = 0
  11825.     
  11826.             /* Update the subscription with the new 'use_interactive' value. */
  11827.  
  11828.             UPDATE sysmergesubscriptions
  11829.                    SET use_interactive_resolver = @use_interactive_bit
  11830.                  WHERE subid = @subid
  11831.             IF @@ERROR <> 0
  11832.                 BEGIN
  11833.                     RAISERROR (14053, 16, -1)
  11834.                     RETURN (1)
  11835.                 END
  11836.             /* If the subscription is enable for Sync Manager, then update the reg value */
  11837.             exec sp_MSsubscription_enabled_for_syncmgr
  11838.                 @publisher, @publisher_db, @publication, @subscriber, @subscriber_db, 
  11839.                 @enabled_for_syncmgr OUT, @regkey OUT
  11840.             IF @@ERROR <> 0
  11841.                 BEGIN
  11842.                     RAISERROR (14053, 16, -1)
  11843.                     RETURN (1)
  11844.                 END
  11845.             if @enabled_for_syncmgr = 1
  11846.                 begin
  11847.                     select @use_interactive_int = convert(int, @use_interactive_bit)
  11848.                     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  11849.                                            @regkey,
  11850.                                            'UseInteractiveResolver',
  11851.                                            'REG_DWORD',
  11852.                                             @use_interactive_int
  11853.                     if @retcode <> 0 OR @@ERROR <> 0
  11854.                         BEGIN
  11855.                             RAISERROR (14053, 16, -1)
  11856.                             RETURN (1)
  11857.                         END
  11858.                 end
  11859.  
  11860.         END
  11861.         
  11862.  
  11863.      
  11864.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) = 'priority'
  11865.     BEGIN
  11866.  
  11867.         select @db_name = db_name from sysmergesubscriptions
  11868.             where (pubid=@pubid) and (subid=@pubid)
  11869.         IF @db_name <> db_name()
  11870.             BEGIN
  11871.                 RAISERROR (20047, 16, -1)
  11872.                 RETURN (1)
  11873.             END
  11874.  
  11875.         /* Only the original publisher can change priority of a global subscriptions */
  11876.  
  11877.         IF @subscriber_type<>1  
  11878.             BEGIN
  11879.                 RAISERROR (20044, 16, -1)  /* Local subscriber does not have priority*/
  11880.                 RETURN (1)
  11881.             END
  11882.  
  11883.          
  11884.         BEGIN TRANSACTION
  11885.         save tran sp_changemergepullsubscription
  11886.             exec dbo.sp_MSchange_priority @subid,  @value
  11887.             select @snapshot_ready=snapshot_ready from sysmergepublications where pubid = @pubid
  11888.             /* Insert the sp_MSchange_priority schema change only if the publication's snapshot is ready */
  11889.             if (@snapshot_ready > 0)
  11890.             begin
  11891.                  select @schemaversion = schemaversion from sysmergeschemachange
  11892.                 if (@schemaversion is NULL)
  11893.                 set @schemaversion = 1
  11894.                 else
  11895.                     select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  11896.                 set @schemaguid = newid()
  11897.                 set @artid = newid()
  11898.                 set @schematype = 8 /* change priority */
  11899.                 select @schematext = 'exec dbo.sp_MSchange_priority '+ '''' + convert(nchar(36),@subid) + '''' + ',' + '''' + @value + '''' 
  11900.                  exec dbo.sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  11901.                 if @@ERROR <> 0 goto Rollback_tran
  11902.             end             
  11903.         COMMIT TRANSACTION
  11904.  
  11905.     END
  11906.     
  11907.     IF LOWER(@property collate SQL_Latin1_General_CP1_CS_AS) IN 
  11908.                            ('publisher_login',
  11909.                             'publisher_password',
  11910.                             'publisher_security_mode',
  11911.                             'distributor',
  11912.                             'distributor_login',
  11913.                             'distributor_password',
  11914.                             'distributor_security_mode',
  11915.                             'ftp_address',
  11916.                             'ftp_port',
  11917.                             'ftp_login',
  11918.                             'ftp_password',
  11919.                             'alt_snapshot_folder',
  11920.                             'working_directory',
  11921.                             'use_ftp',
  11922.                             'offload_agent',
  11923.                             'offload_server',
  11924.                             'dynamic_snapshot_location')
  11925.     BEGIN
  11926.         EXEC @retcode = sp_change_subscription_properties @publisher = @publisher,
  11927.                                                           @publisher_db = @publisher_db,
  11928.                                                           @publication = @publication,
  11929.                                                           @property = @property,
  11930.                                                           @value = @value,
  11931.                                                           @publication_type = 2
  11932.         IF @retcode <> 0
  11933.             RETURN 1
  11934.     END
  11935.  
  11936.  
  11937.     /*
  11938.     ** Return succeed.
  11939.     */
  11940.  
  11941.     RAISERROR (14054, 10, -1)
  11942.     RETURN (0)
  11943. Rollback_tran:
  11944.     rollback tran sp_changemergepullsubscription
  11945.     commit tran
  11946.     return(1)
  11947. go
  11948.  
  11949. exec dbo.sp_MS_marksystemobject sp_changemergepullsubscription 
  11950. go
  11951.  
  11952. grant execute on dbo.sp_changemergepullsubscription to public
  11953. go
  11954.  
  11955.  
  11956. raiserror('Creating procedure sp_helpmergepullsubscription', 0,1)
  11957. GO
  11958.  
  11959. CREATE PROCEDURE sp_helpmergepullsubscription(
  11960.     @publication         sysname = '%',        /* Publication name */
  11961.     @publisher            sysname = '%',      /* Publisher server */
  11962.     @publisher_db        sysname = '%',      /* Publication database */
  11963.     @subscription_type    nvarchar(10) = 'pull'    /* Show only pull subscriptions */
  11964.     )AS
  11965.     
  11966.     SET NOCOUNT ON
  11967.  
  11968.     /*
  11969.     ** Declarations.
  11970.     */
  11971.  
  11972.     declare @retcode             int
  11973.     declare @srvid                 int
  11974.     declare    @pubid                 uniqueidentifier
  11975.     declare    @subid                 uniqueidentifier
  11976.     declare    @partnerid             uniqueidentifier
  11977.     declare @cursor_open        int
  11978.     declare @subscriber            sysname
  11979.     declare @subscriber_db        sysname
  11980.     declare @subscription_set     nvarchar(10)
  11981.     declare @publisher_local    sysname
  11982.     declare @publisher_db_local    sysname
  11983.     declare @publication_local    sysname
  11984.     declare @subscription_name     nvarchar(1000)
  11985.     declare @regkey                nvarchar(1000)
  11986.     declare @syncmgr_keyexist                int
  11987.     declare @helpsubscriptioncursor_open    int
  11988.     
  11989.  
  11990.     /*
  11991.     ** Initializations.
  11992.     */
  11993.     set @cursor_open             = 0                    
  11994.  
  11995.     select @publisher_db = RTRIM(@publisher_db)
  11996.     select @publication = RTRIM(@publication)
  11997.     
  11998.     -- For attach
  11999.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  12000.         -- The database is attached from a subscription copy file without using
  12001.         -- sp_attachsubscription. Return nothing
  12002.         return 0
  12003.  
  12004.     /*
  12005.     **    Calling sp_help* is all right whether current database is enabled for pub/sub or not
  12006.     */
  12007.  
  12008.     IF not exists (select * from sysobjects where name='sysmergesubscriptions')
  12009.         RETURN (0)
  12010.  
  12011.     /* Security check */
  12012.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  12013.     if @@ERROR <> 0 or @retcode <> 0
  12014.         return(1)
  12015.  
  12016.     set @subscriber = @@SERVERNAME     
  12017.     set @subscriber_db = DB_NAME()
  12018.  
  12019.     /*
  12020.     ** Parameter Check: @publisher
  12021.     ** Check to make sure that the publisher is defined
  12022.     */
  12023.     IF @publisher <> '%' AND @publisher IS NOT NULL
  12024.     BEGIN
  12025.         EXECUTE @retcode = dbo.sp_validname @publisher
  12026.  
  12027.         IF @@ERROR <> 0 OR @retcode <> 0
  12028.                RETURN (1)
  12029.     END
  12030.  
  12031.     /*
  12032.     ** Parameter Check:  @publication.
  12033.     ** If the publication name is specified, check to make sure that it
  12034.     ** conforms to the rules for identifiers and that the publication
  12035.     ** actually exists.  Disallow NULL.
  12036.     */
  12037.     if @publication IS NULL
  12038.         BEGIN
  12039.             RAISERROR (14043, 16, -1, '@publication')
  12040.             RETURN (1)
  12041.         END
  12042.  
  12043.     /*
  12044.     ** Parameter Check: @subscription_type.
  12045.     ** Set subscription_typeid based on the @subscription_type specified.
  12046.     **
  12047.     **   subscription_type    subscription_type
  12048.     **   =================    ===============
  12049.     **             0             push
  12050.     **             1             pull
  12051.     **              0,1            both
  12052.     */
  12053.     if LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('push', 'pull', 'both')
  12054.         BEGIN
  12055.               RAISERROR (14128, 16, -1)
  12056.             RETURN (1)
  12057.         END
  12058.     IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'both'
  12059.         set @subscription_set = '(0, 1)'
  12060.     else IF LOWER(@subscription_type collate SQL_Latin1_General_CP1_CS_AS) = 'push'
  12061.         set @subscription_set = '(0)'
  12062.     else 
  12063.         set @subscription_set = '(1,2)'   -- including pull subscription and pull/anonymous subscription
  12064.  
  12065.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  12066.         type = 'U' AND
  12067.         name = 'MSsubscription_properties')
  12068.         RETURN (0)
  12069.  
  12070.     /*
  12071.     ** Get subscriptions
  12072.     */
  12073.     
  12074.     create table #helpmergepullsubscription
  12075.                 (
  12076.                     publication                sysname        collate database_default not null,
  12077.                     publisher                sysname        collate database_default not null,
  12078.                     publisher_db            sysname        collate database_default not null,
  12079.                     subscriber                sysname        collate database_default not null,
  12080.                     subscriber_db             sysname        collate database_default not null,
  12081.                     status                    int         NOT NULL,
  12082.                     subscriber_type         int            NOT NULL,
  12083.                     subscription_type         int            NOT NULL,
  12084.                     priority                float(8)    NOT NULL,
  12085.                     sync_type                tinyint        NOT NULL,
  12086.                     description                nvarchar(255)     collate database_default null,
  12087.                     merge_jobid                binary(16)        NULL,
  12088.                     enabled_for_syncmgr        int                NULL,
  12089.                     last_updated            nvarchar(26)     collate database_default null,
  12090.                     use_interactive_resolver     int            NULL,
  12091.                     subid                    uniqueidentifier    not NULL,
  12092.                     last_sync_status        int                NULL,
  12093.                     last_sync_summary        sysname            collate database_default null
  12094.                 )
  12095.  
  12096.     IF @publisher IS NULL and @publisher_db IS NULL
  12097.         BEGIN
  12098.             select @subid = subid from sysmergesubscriptions where subid = partnerid
  12099.             set @partnerid = @subid
  12100.             -- show the loopback subscription
  12101.             insert into #helpmergepullsubscription 
  12102.                 select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  12103.                     subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  12104.                     subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, 
  12105.                     convert(nvarchar(12), subs1.last_sync_date, 112) + substring(convert(nvarchar(24), subs1.last_sync_date, 121), 11,13), 
  12106.                     subs1.use_interactive_resolver, @subid, subs1.last_sync_status, subs1.last_sync_summary
  12107.                 FROM      sysmergesubscriptions     subs1,
  12108.                           sysmergesubscriptions     subs2,
  12109.                           MSmerge_replinfo         replinfo,
  12110.                         master.dbo.sysservers     servers1,
  12111.                         master.dbo.sysservers     servers2,
  12112.                         sysmergepublications     pubs
  12113.                 where subs1.subid = @subid
  12114.                     and subs2.subid = @partnerid
  12115.                     and pubs.pubid = subs1.pubid
  12116.                     and servers1.srvid = subs1.srvid
  12117.                     and servers2.srvid = subs2.srvid
  12118.                     and subs1.subid = subs1.partnerid 
  12119.                     and replinfo.repid = subs1.subid 
  12120.             
  12121.         END
  12122.     else
  12123.         begin
  12124.             declare #cursor cursor local FAST_FORWARD FOR select DISTINCT sub.subid, sub.partnerid 
  12125.                 FROM sysmergesubscriptions     sub,
  12126.                 sysmergesubscriptions         sub1, 
  12127.                 master.dbo.sysservers        ss,  
  12128.                 master.dbo.sysservers        ss1, 
  12129.                 sysmergepublications         pub 
  12130.                  WHERE ((@subscriber = N'%') OR (UPPER(ss.srvname) = UPPER(@subscriber) collate database_default)) 
  12131.                     AND ((@publisher = N'%') OR (UPPER(ss1.srvname) = UPPER(@publisher) collate database_default)) 
  12132.                     AND sub1.srvid = ss1.srvid 
  12133.                        AND sub.srvid = ss.srvid  
  12134.                        AND pub.name LIKE  @publication  
  12135.                        AND sub.pubid = pub.pubid 
  12136.                                 AND ((@subscriber_db = N'%') OR (sub.db_name = @subscriber_db collate database_default))
  12137.                                 AND ((@publisher_db = N'%') OR (sub1.db_name = @publisher_db collate database_default))
  12138.                     AND sub1.pubid = pub.pubid 
  12139.                     AND (sub.subscription_type=1 or sub.subscription_type=2) 
  12140.                 FOR READ ONLY
  12141.  
  12142.             open #cursor
  12143.             select @cursor_open = 1                    
  12144.             fetch next from #cursor into @subid, @partnerid
  12145.             while (@@fetch_status <> -1)
  12146.                 begin
  12147.                     insert into #helpmergepullsubscription 
  12148.                         select pubs.name, servers2.srvname, subs2.db_name, servers1.srvname, subs1.db_name, 
  12149.                             subs1.status, subs1.subscriber_type, subs1.subscription_type, subs1.priority, 
  12150.                             subs1.sync_type, subs1.description, replinfo.merge_jobid, 0, 
  12151.                             convert(nvarchar(12), subs1.last_sync_date, 112) + substring(convert(nvarchar(24), subs1.last_sync_date, 121), 11,13), 
  12152.                             subs1.use_interactive_resolver, @subid, subs1.last_sync_status, subs1.last_sync_summary
  12153.                         FROM      sysmergesubscriptions     subs1,
  12154.                                   sysmergesubscriptions     subs2,
  12155.                                   MSmerge_replinfo         replinfo,
  12156.                                 master.dbo.sysservers    servers1,
  12157.                                 master.dbo.sysservers    servers2,
  12158.                                 sysmergepublications     pubs
  12159.                         where subs1.subid = @subid
  12160.                             and subs2.subid = @partnerid
  12161.                             and pubs.pubid = subs1.pubid
  12162.                             and servers1.srvid = subs1.srvid
  12163.                             and servers2.srvid = subs2.srvid
  12164.                             and @subid <> @partnerid -- do not show the loopback subscription
  12165.                             and replinfo.repid = subs1.subid 
  12166.         
  12167.                     if @@ERROR <> 0
  12168.                         begin
  12169.                             set @retcode = 1
  12170.                             goto DONE
  12171.                         end                    
  12172.                 fetch next from #cursor into @subid, @partnerid
  12173.             end
  12174.         end
  12175.         declare #helpsubscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  12176.             select DISTINCT publisher, publisher_db, publication
  12177.                    FROM #helpmergepullsubscription
  12178.                 FOR READ ONLY
  12179.         create table #syncmgr_keyexist (syncmgr_keyexist int)
  12180.         open #helpsubscriptioncursor
  12181.         select @helpsubscriptioncursor_open = 1                    
  12182.         fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  12183.         while (@@fetch_status <> -1)
  12184.         begin
  12185.             set @subscription_name = @publisher_local + ':' + @publisher_db_local + ':' + @publication_local + ':' + @subscriber + ':' + @subscriber_db
  12186.             /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  12187.             set @subscription_name = REPLACE(@subscription_name,'\','/')
  12188.             set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  12189.             insert into #syncmgr_keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  12190.             select @syncmgr_keyexist = syncmgr_keyexist from #syncmgr_keyexist
  12191.             update #helpmergepullsubscription set enabled_for_syncmgr = @syncmgr_keyexist 
  12192.                 where UPPER(publisher) = UPPER(@publisher_local)
  12193.                     and publisher_db = @publisher_db_local
  12194.                     and publication = @publication_local
  12195.             fetch next from #helpsubscriptioncursor into @publisher_local, @publisher_db_local, @publication_local
  12196.         end
  12197.  
  12198.     select 'subscription_name'= hs.publisher + ':' + hs.publisher_db + ':' + hs.publication collate database_default, hs.publication, hs.publisher,
  12199.             hs.publisher_db, hs.subscriber, hs.subscriber_db, hs.status, hs.subscriber_type, hs.subscription_type,
  12200.             hs.priority, hs.sync_type, hs.description, hs.merge_jobid, hs.enabled_for_syncmgr, hs.last_updated, sp.publisher_login,
  12201.             sp.publisher_password, sp.publisher_security_mode, sp.distributor, sp.distributor_login, 
  12202.             sp.distributor_password, sp.distributor_security_mode, 'ftp_address' = null, 'ftp_port' = 0, 
  12203.             'ftp_login' = null, 'ftp_password' = null, sp.alt_snapshot_folder, sp.working_directory, sp.use_ftp, 
  12204.             sp.offload_agent, sp.offload_server, hs.use_interactive_resolver, hs.subid, 
  12205.             sp.dynamic_snapshot_location, hs.last_sync_status, hs.last_sync_summary
  12206.                 from #helpmergepullsubscription hs
  12207.      left outer join MSsubscription_properties sp
  12208.                   on hs.publisher = sp.publisher collate database_default
  12209.                  and hs.publisher_db = sp.publisher_db collate database_default
  12210.                  and hs.publication = sp.publication collate database_default
  12211.             order by hs.publisher, hs.publisher_db, hs.publication, hs.subscriber, hs.subscriber_db
  12212.          
  12213.     select @retcode = 0
  12214. DONE:
  12215.     if (@cursor_open = 1)
  12216.         begin
  12217.             close #cursor
  12218.             deallocate #cursor
  12219.         end            
  12220.     --drop table #helpmergepullsubscription
  12221.  
  12222.     return @retcode    
  12223. go
  12224. exec dbo.sp_MS_marksystemobject sp_helpmergepullsubscription
  12225. go
  12226.  
  12227. grant execute on dbo.sp_helpmergepullsubscription to public
  12228. go
  12229.  
  12230. raiserror('Creating procedure sp_addmergepullsubscription_agent', 0,1)
  12231. GO
  12232. CREATE PROCEDURE sp_addmergepullsubscription_agent (
  12233.     @name                            sysname = NULL,
  12234.     @publisher                        sysname,                          /* Publisher server */
  12235.     @publisher_db                    sysname,                          /* Publisher database */
  12236.     @publication                     sysname,                          /* Publication name */
  12237.     @publisher_security_mode        int = 1,
  12238.     @publisher_login                sysname = NULL,
  12239.     @publisher_password                sysname = NULL,
  12240.     @publisher_encrypted_password    bit = 0,
  12241.     @subscriber                        sysname = NULL,
  12242.     @subscriber_db                    sysname = NULL,
  12243.     @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  12244.     @subscriber_login                sysname = NULL,
  12245.     @subscriber_password            sysname = NULL,
  12246.     @distributor                    sysname = @@SERVERNAME,
  12247.     @distributor_security_mode        int = 0,                        /* 0 standard; 1 integrated */
  12248.     @distributor_login                sysname = 'sa',
  12249.     @distributor_password            sysname = NULL,
  12250.     @encrypted_password                bit = 0,            /* distributor password encrypted or not */
  12251.     @frequency_type                  int = NULL,
  12252.     @frequency_interval             int = NULL,                
  12253.     @frequency_relative_interval     int = NULL, 
  12254.     @frequency_recurrence_factor     int = NULL, 
  12255.     @frequency_subday                 int = NULL,
  12256.     @frequency_subday_interval         int = NULL,       
  12257.     @active_start_time_of_day         int = NULL, 
  12258.     @active_end_time_of_day         int = NULL,         
  12259.     @active_start_date                 int = NULL, 
  12260.     @active_end_date                 int = NULL,
  12261.     @optional_command_line             nvarchar(255) = '',            /* Optional command line arguments */
  12262.     @merge_jobid                    binary(16) = NULL OUTPUT,
  12263.     @enabled_for_syncmgr             nvarchar(5) = 'false', /* Enabled for SYNCMGR: true or false */
  12264.     @ftp_address                     sysname = NULL,
  12265.     @ftp_port                         int = NULL,
  12266.     @ftp_login                         sysname = NULL,
  12267.     @ftp_password                     sysname = NULL,
  12268.     @alt_snapshot_folder              nvarchar(255) = NULL,
  12269.     @working_directory                nvarchar(255) = NULL,
  12270.     @use_ftp                          nvarchar(5) = 'false',
  12271.     @reserved                         nvarchar(100) = N'', -- Not default to null because null problems in conditional expressions.
  12272.     @use_interactive_resolver       nvarchar(5) = 'false',
  12273.     @offloadagent                     nvarchar(5) = 'false',
  12274.     @offloadserver                    sysname = null,
  12275.     -- Used by DMO scripting
  12276.     @job_name                        sysname = NULL,
  12277.     @dynamic_snapshot_location      nvarchar(260) = NULL
  12278.     ) AS
  12279.  
  12280.     SET NOCOUNT ON
  12281.  
  12282.     /*
  12283.     ** Declarations.
  12284.     */
  12285.     declare @command                 nvarchar(4000)
  12286.     declare @retcode                 int
  12287.     declare @database                sysname
  12288.     declare @repid                    uniqueidentifier
  12289.     declare @pubid                    uniqueidentifier
  12290.     declare @subscriber_srvid        int 
  12291.     declare @publisher_srvid        int 
  12292.     declare @name_id                nvarchar(50)
  12293.     declare @subscriber_typeid        int
  12294.     declare @subscription_type_id    int
  12295.     declare @category_name            sysname
  12296.     declare @platform_nt            binary
  12297.     DECLARE @subscriber_enc_password     nvarchar(524)
  12298.     DECLARE @publisher_enc_password     nvarchar(524)
  12299.     DECLARE @distributor_enc_password     nvarchar(524)
  12300.     DECLARE @use_ftp_bit                bit
  12301.     declare @use_interactive_bit        bit
  12302.     DECLARE @offload_agent_bit          bit
  12303.  
  12304.     select @platform_nt = 0x1
  12305.  
  12306.     SELECT @use_ftp_bit = 0
  12307.  
  12308.     -- For attach check
  12309.     if exists (select * from sysobjects where name = 'MSrepl_restore_stage')
  12310.     begin
  12311.         raiserror(21211, 16, -1)
  12312.         return 1
  12313.     end
  12314.  
  12315.     -- Set null @optional_command_line to empty string to avoid string concat problem
  12316.     if @optional_command_line is null
  12317.         set @optional_command_line = ''
  12318.         else
  12319.                 set @optional_command_line = N' ' + LTRIM( RTRIM(@optional_command_line) ) + N' '
  12320.  
  12321.     IF @distributor_password = N''
  12322.         select @distributor_password = NULL
  12323.  
  12324.     IF @publisher_password = N''
  12325.         select @publisher_password = NULL
  12326.  
  12327.     IF @ftp_password = N''
  12328.         select @ftp_password = NULL
  12329.  
  12330.     /*
  12331.     ** Parameter Check: @subscriber and @subscriber_db
  12332.     */
  12333.  
  12334.     if @subscriber IS NULL or rtrim(@subscriber) = ''
  12335.         SELECT @subscriber = @@SERVERNAME
  12336.  
  12337.     if @subscriber_db IS NULL or rtrim(@subscriber_db) = ''
  12338.         SELECT @subscriber_db = DB_NAME()
  12339.     
  12340.     EXECUTE @retcode = dbo.sp_validname @subscriber
  12341.     IF @@ERROR <> 0 OR @retcode <> 0
  12342.        RETURN (1)
  12343.     
  12344.     EXECUTE @retcode = dbo.sp_validname @subscriber_db
  12345.     IF @@ERROR <> 0 OR @retcode <> 0
  12346.        RETURN (1)
  12347.  
  12348.     -- Parameter check: @subscriber_security_mode    
  12349.     if @subscriber_security_mode is null
  12350.     begin
  12351.         if ( platform() & @platform_nt ) = @platform_nt
  12352.             select @subscriber_security_mode = 1
  12353.         else
  12354.             select @subscriber_security_mode = 0
  12355.     end    
  12356.  
  12357.     /* 
  12358.     ** Parameter check: @alt_snapshot_folder 
  12359.     ** @alt_snapshot_folder and @use_ftp are mutually exclusive    
  12360.     ** @dynamic_snapshot_location is incompatible with both 
  12361.     ** @alt_snapshot_folder and @use_ftp
  12362.     */
  12363.  
  12364.     IF @alt_snapshot_folder <> N'' AND @alt_snapshot_folder IS NOT NULL
  12365.     BEGIN
  12366.         IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = N'true'
  12367.         BEGIN
  12368.             RAISERROR(21146, 16, -1)
  12369.             RETURN (1)
  12370.         END
  12371.         IF @dynamic_snapshot_location <> N'' AND @dynamic_snapshot_location IS NOT NULL
  12372.         BEGIN
  12373.             RAISERROR(21341, 16, -1)
  12374.             RETURN (1)
  12375.         END
  12376.     END
  12377.  
  12378.        /*
  12379.     ** Parameter Check: @use_interactive_resolver  
  12380.     */
  12381.     if LOWER(@use_interactive_resolver collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  12382.         BEGIN
  12383.             RAISERROR (14148, 16, -1, '@use_interactive_resolver')
  12384.             RETURN (1)
  12385.         END
  12386.     if LOWER(@use_interactive_resolver collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  12387.         set @use_interactive_bit = 1
  12388.     else 
  12389.         set @use_interactive_bit = 0
  12390.  
  12391.     /* 
  12392.     ** Parameter check: @use_ftp
  12393.     ** Must be 'true' or 'false'
  12394.     */
  12395.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) NOT IN ('true', 'false')
  12396.     BEGIN
  12397.         RAISERROR (14148, 16, -1, '@use_ftp')
  12398.         RETURN (1)
  12399.     END
  12400.     
  12401.     IF LOWER(@use_ftp collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  12402.     BEGIN
  12403.         /*
  12404.         ** Ftp file transfer is incompatible with @dynamic_snapshot_location
  12405.         */
  12406.         IF @dynamic_snapshot_location <> N'' AND @dynamic_snapshot_location IS NOT NULL
  12407.         BEGIN
  12408.             RAISERROR (21342, 16, -1)
  12409.             RETURN (1)
  12410.         END
  12411.  
  12412.         SELECT @use_ftp_bit = 1
  12413.  
  12414.     END
  12415.     ELSE
  12416.     BEGIN
  12417.         SELECT @use_ftp_bit = 0
  12418.     END
  12419.  
  12420.     /*
  12421.     ** Parameter Check: @offloadserver
  12422.     ** If @offloadagent = 'true' then @offloadserver cannot be null
  12423.     */
  12424.     SELECT @offloadagent = LOWER(@offloadagent collate SQL_Latin1_General_CP1_CS_AS)
  12425.     IF @offloadagent NOT IN ('true', 'false')
  12426.     BEGIN
  12427.         RAISERROR (14148, 16, -1, '@offloadagent')
  12428.         RETURN (1)
  12429.     END
  12430.  
  12431.     IF @offloadagent = 'true'
  12432.     BEGIN
  12433.         SELECT @offload_agent_bit = 1
  12434.     END
  12435.     ELSE
  12436.     BEGIN
  12437.         SELECT @offload_agent_bit = 0
  12438.     END
  12439.  
  12440.     IF @offload_agent_bit = 1 AND (@offloadserver IS NULL or
  12441.                                @offloadserver = N'')
  12442.     BEGIN
  12443.         RAISERROR(21215, 16, -1)
  12444.         RETURN (1)
  12445.     END
  12446.  
  12447.     IF UPPER(@offloadserver) = UPPER(@@SERVERNAME) AND
  12448.        @offload_agent_bit = 1
  12449.     BEGIN
  12450.         RAISERROR(21227, 16, -1)
  12451.         RETURN (1)
  12452.     END
  12453.  
  12454.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  12455.     IF @retcode <> 0 OR @@ERROR <> 0
  12456.         RETURN (1)
  12457.  
  12458.     -- Make sure that there are no leading or trailing blanks
  12459.     -- in the dynamic snapshot location
  12460.     select @dynamic_snapshot_location = rtrim(ltrim(@dynamic_snapshot_location))
  12461.  
  12462.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1)
  12463.     begin
  12464.         RAISERROR(21038, 16, -1)
  12465.         RETURN (1)
  12466.     end
  12467.  
  12468.     select @subscription_type_id = 1 /* pull agent only */
  12469.     /*
  12470.     ** Set Default schedule values if NULL is specified
  12471.     ** The default are not implemented during parmeter defintion because this procedure
  12472.     ** is can be called from sp_addmergesubscription.
  12473.     */
  12474.     if @frequency_type is NULL
  12475.         set @frequency_type = 4        /* Daily */
  12476.     if @frequency_interval is NULL
  12477.         set @frequency_interval = 1
  12478.     if @frequency_relative_interval is NULL
  12479.         set @frequency_relative_interval = 1
  12480.     if @frequency_recurrence_factor is NULL
  12481.         set @frequency_recurrence_factor = 0
  12482.     if @frequency_subday is NULL
  12483.         set @frequency_subday = 8    /* Hour */
  12484.     if @frequency_subday_interval is NULL
  12485.         set @frequency_subday_interval = 1
  12486.     if @active_start_time_of_day is NULL
  12487.         set @active_start_time_of_day = 0
  12488.     if @active_end_time_of_day is NULL
  12489.         set @active_end_time_of_day = 235959
  12490.     if @active_start_date is NULL
  12491.         set @active_start_date = 0
  12492.     if @active_end_date is NULL
  12493.         set @active_end_date = 99991231
  12494.  
  12495.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@@SERVERNAME) collate database_default
  12496.     IF @subscriber_srvid IS NULL
  12497.         BEGIN
  12498.            RAISERROR (14010, 16, -1)
  12499.            RETURN (1)     
  12500.         END
  12501.             
  12502.     select @pubid = pubid from sysmergepublications 
  12503.         where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  12504.     IF @pubid is NULL
  12505.         begin
  12506.             RAISERROR (20026, 16, -1, @publication)
  12507.             RETURN (1)
  12508.         end
  12509.             
  12510.     select @repid = subid, @subscriber_typeid = subscriber_type from sysmergesubscriptions
  12511.             where srvid = @subscriber_srvid and pubid<>subid and pubid = @pubid and db_name = @subscriber_db
  12512.  
  12513.     if @subscriber_typeid = 3 set @subscription_type_id = 2 /* This corresponds to anonymous subscription */
  12514.  
  12515.     if (@subscription_type_id <> 0)
  12516.     begin
  12517.         if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  12518.         begin
  12519.             raiserror(3217, 16, -1, '@subscriber_login')
  12520.             return (1)
  12521.         end
  12522.     end
  12523.  
  12524.     if (@distributor_security_mode = 0) and (@distributor_login IS NULL or rtrim(@distributor_login) = '')
  12525.     begin
  12526.         raiserror(3217, 16, -1, '@distributor_login')
  12527.         return (1)
  12528.     end
  12529.  
  12530.     if (@publisher_security_mode = 0) and (@publisher_login IS NULL or rtrim(@publisher_login) = '')
  12531.     begin
  12532.         raiserror(3217, 16, -1, '@publisher_login')
  12533.         return (1)
  12534.     end
  12535.  
  12536.     IF NOT EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  12537.     begin
  12538.         raiserror(14027, 16, -1, 'The subscription properties table ''MSsubscription_properties''')
  12539.         return (1)
  12540.     end
  12541.     
  12542.     declare @job_existing bit
  12543.     -- For scripting
  12544.     if @job_name is null
  12545.         select @job_existing = 0
  12546.     else
  12547.     begin
  12548.         select @job_existing = 1
  12549.         select @name = @job_name
  12550.     end
  12551.  
  12552.     /*
  12553.     ** Construct unique task name if @name = NULL
  12554.     */
  12555.     IF @name IS NULL
  12556.         begin
  12557.              SELECT @name = CONVERT(nvarchar(23),@publisher ) + '-' + CONVERT(nvarchar(23),@publisher_db) + '-' + 
  12558.                         CONVERT(nvarchar(23),@publication) + '-' + CONVERT(nvarchar(23),@subscriber) + '-' +
  12559.                         CONVERT(nvarchar(23), @subscriber_db) + '- 0'
  12560.         end
  12561.     else
  12562.     begin
  12563.         /*
  12564.         ** validate name
  12565.         */
  12566.         exec @retcode = dbo.sp_MSreplcheck_name @name
  12567.         if @@ERROR <> 0 or @retcode <> 0
  12568.             return(1)
  12569.  
  12570.     end
  12571.  
  12572.     -- Get property values.
  12573.     if @reserved = 'no_change_to_properties'
  12574.     begin
  12575.         -- Get the distributor value. It will be used in agent command line.
  12576.         select @distributor = distributor, 
  12577.             @enabled_for_syncmgr = case enabled_for_syncmgr
  12578.                 when 0 then 'false'
  12579.                 when 1 then    'true'
  12580.                 end
  12581.             from MSsubscription_properties where
  12582.             UPPER(publisher) = UPPER(@publisher)
  12583.             and publisher_db =  @publisher_db
  12584.             and publication = @publication
  12585.     end
  12586.  
  12587.     begin tran
  12588.     save tran sp_addpullsub_agent
  12589.  
  12590.     if @job_existing = 0
  12591.     begin
  12592.         /* Construct task command */
  12593.         select @command = '-Publisher ' + QUOTENAME(@publisher) + ' -PublisherDB ' + QUOTENAME(@publisher_db) + ' '
  12594.         select @command = @command + '-Publication ' + QUOTENAME(@publication) + ' '
  12595.         select @command = @command + '-Subscriber ' + QUOTENAME(@@SERVERNAME)  + ' '
  12596.         select @command = @command + '-SubscriberDB ' + QUOTENAME(db_name()) + ' '
  12597.         SELECT @command = @command + '-SubscriptionType ' + convert(nvarchar(10), @subscription_type_id)  + ' '
  12598.         
  12599.         select @command = @command + '-SubscriberSecurityMode ' + 
  12600.             convert(nvarchar(10),@subscriber_security_mode) + ' '
  12601.         if @subscriber_login is not NULL
  12602.             select @command = @command + '-SubscriberLogin ' + quotename(@subscriber_login) + ' '
  12603.         if @subscriber_password is not NULL
  12604.         begin
  12605.             set @subscriber_enc_password = @subscriber_password
  12606.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_enc_password OUTPUT
  12607.             select @command = @command + '-SubscriberEncryptedPassword ' + quotename(@subscriber_enc_password) + ' '
  12608.         end
  12609.         
  12610.         select @command = @command + @optional_command_line
  12611.         select @command = @command + ' -Distributor ' + QUOTENAME(@distributor) + ' '
  12612.  
  12613.         if @offload_agent_bit = 1
  12614.             select @command = @command + N'-Offload ' + @offloadserver + N' '
  12615.         
  12616.         select @dynamic_snapshot_location = rtrim(ltrim(@dynamic_snapshot_location))
  12617.         if @dynamic_snapshot_location is not null and 
  12618.            @dynamic_snapshot_location <> N''
  12619.             select @command = @command + N'-DynamicSnapshotLocation ' + fn_replquotename(@dynamic_snapshot_location) collate database_default + N' '
  12620.  
  12621.         select @database = db_name()
  12622.  
  12623.         -- Get Merge category name (assumes category_id = 14)
  12624.         select @category_name = name FROM msdb.dbo.syscategories where category_id = 14
  12625.  
  12626.         EXEC @retcode = dbo.sp_MSadd_repl_job
  12627.                 @name = @name,
  12628.                 @subsystem = 'Merge',
  12629.                 @server = @@SERVERNAME,
  12630.                 @databasename = @database,
  12631.                 @enabled = 1,
  12632.                 @freqtype = @frequency_type,
  12633.                 @freqinterval = @frequency_interval,
  12634.                 @freqsubtype = @frequency_subday,
  12635.                 @freqsubinterval = @frequency_subday_interval,
  12636.                 @freqrelativeinterval = @frequency_relative_interval,
  12637.                 @freqrecurrencefactor = @frequency_recurrence_factor,
  12638.                 @activestartdate = @active_start_date,
  12639.                 @activeenddate = @active_end_date,
  12640.                 @activestarttimeofday = @active_start_time_of_day,
  12641.                 @activeendtimeofday = @active_end_time_of_day,
  12642.                 @command = @command,
  12643.                 @retryattempts = 10,
  12644.                 @retrydelay = 1,
  12645.                 @category_name = @category_name,
  12646.                 @job_id = @merge_jobid OUTPUT
  12647.  
  12648.         if @@ERROR <> 0 or @retcode <> 0 goto Rollback_tran
  12649.     end
  12650.     else
  12651.     begin
  12652.         select @merge_jobid = job_id from msdb..sysjobs_view where 
  12653.             name = @name collate database_default and
  12654.             UPPER(originating_server) = UPPER(CONVERT(sysname, SERVERPROPERTY('ServerName')))
  12655.         if @merge_jobid IS NULL
  12656.         begin
  12657.             -- Message from msdb.dbo.sp_verify_job_identifiers
  12658.             RAISERROR(14262, -1, -1, 'Job', @name)          
  12659.             goto Rollback_tran
  12660.         end
  12661.     end
  12662.  
  12663.  
  12664.     if @reserved <> 'attach_subscription' and (@subscription_type_id = 1) OR (@subscription_type_id = 2)
  12665.     begin
  12666.         IF NOT EXISTS (select * from MSsubscription_properties 
  12667.             where UPPER(publisher) = UPPER(@publisher)
  12668.             and publisher_db =  @publisher_db
  12669.             and publication = @publication) 
  12670.         BEGIN
  12671.             
  12672.             -- Copy the passwords to new value before attempting to encrypt
  12673.             set @distributor_enc_password = @distributor_password
  12674.             set @publisher_enc_password = @publisher_password
  12675.  
  12676.             IF (@encrypted_password = 0)
  12677.             -- Encrypt the password
  12678.             BEGIN
  12679.                 EXEC @retcode = master.dbo.xp_repl_encrypt @distributor_enc_password OUTPUT
  12680.                 IF @@error <> 0 OR @retcode <> 0 goto Rollback_tran
  12681.             END
  12682.     
  12683.             IF (@publisher_encrypted_password = 0)
  12684.             -- Encrypt the password
  12685.             BEGIN
  12686.                 EXEC @retcode = master.dbo.xp_repl_encrypt @publisher_enc_password OUTPUT
  12687.                 IF @@error <> 0 OR @retcode <> 0 goto Rollback_tran
  12688.             END
  12689.     
  12690.             INSERT INTO MSsubscription_properties 
  12691.             (publisher, publisher_db, publication, publication_type, 
  12692.              publisher_login,publisher_password, publisher_security_mode, 
  12693.              distributor, distributor_login, distributor_password, 
  12694.              distributor_security_mode, ftp_address, ftp_port, ftp_login, 
  12695.              ftp_password, alt_snapshot_folder, working_directory, use_ftp,
  12696.              offload_agent, offload_server, dynamic_snapshot_location)
  12697.             values 
  12698.             (@publisher, @publisher_db, @publication, 2, @publisher_login, 
  12699.              @publisher_enc_password, @publisher_security_mode, @distributor, 
  12700.              @distributor_login, @distributor_enc_password, 
  12701.              @distributor_security_mode, null, null, null,
  12702.              null, @alt_snapshot_folder, @working_directory, @use_ftp_bit,
  12703.              @offload_agent_bit, @offloadserver, @dynamic_snapshot_location)
  12704.         END
  12705.     end
  12706.  
  12707.         
  12708.     /* Update merge joibd for this pull subscription */
  12709.     UPDATE MSmerge_replinfo set merge_jobid = @merge_jobid WHERE repid = @repid
  12710.  
  12711.     /* Update the distributor column in sysmergesubscriptions */
  12712.     UPDATE sysmergesubscriptions set 
  12713.             use_interactive_resolver = @use_interactive_bit,
  12714.             distributor = @distributor 
  12715.                 WHERE subid = @repid
  12716.     
  12717.     /* Conditional support for MobileSync */
  12718.     if LOWER(@enabled_for_syncmgr collate SQL_Latin1_General_CP1_CS_AS) = 'true'
  12719.     BEGIN
  12720.         /* Call sp_MSregistersubscription so that the subscription can be synchronized via MobileSync etc. */
  12721.         exec @retcode = dbo.sp_MSregistersubscription @replication_type = 2,
  12722.                                     @publisher = @publisher,
  12723.                                     @publisher_security_mode = @publisher_security_mode,
  12724.                                     @publisher_login = @publisher_login,
  12725.                                     @publisher_password = @publisher_password,
  12726.                                     @publisher_db = @publisher_db,
  12727.                                     @publication = @publication,
  12728.                                     @subscriber = @subscriber,
  12729.                                     @subscriber_db = @subscriber_db,
  12730.                                     @subscriber_security_mode = @subscriber_security_mode,
  12731.                                     @subscriber_login = @subscriber_login,
  12732.                                     @subscriber_password = @subscriber_password,
  12733.                                     @distributor = @distributor,
  12734.                                     @distributor_security_mode = @distributor_security_mode,
  12735.                                     @distributor_login = @distributor_login,
  12736.                                     @distributor_password = @distributor_password,
  12737.                                     @subscription_id = @repid,
  12738.                                     @subscription_type = @subscription_type_id,
  12739.                                     @use_interactive_resolver = @use_interactive_bit
  12740.  
  12741.         IF @@ERROR <> 0 or @retcode <> 0 goto Rollback_tran
  12742.     END
  12743.  
  12744. commit tran
  12745.     RETURN (0)
  12746. Rollback_tran:
  12747.     rollback tran sp_addpullsub_agent
  12748.     commit tran
  12749.     return(1)
  12750. GO
  12751.  
  12752. exec dbo.sp_MS_marksystemobject sp_addmergepullsubscription_agent
  12753. go
  12754.  
  12755. raiserror('Creating procedure sp_MSget_mergepullsubsagent_owner', 0,1)
  12756. GO
  12757. CREATE PROCEDURE sp_MSget_mergepullsubsagent_owner(
  12758.     @publication         sysname = NULL,                  /* Publication name */
  12759.     @publisher            sysname = NULL,              /* Publisher server */
  12760.     @publisher_db        sysname = NULL,              /* Publication database */
  12761.     @owner_sid          varbinary(85) OUTPUT
  12762.     )AS
  12763.     
  12764.     declare @srvid  int
  12765.     declare @pubid  uniqueidentifier 
  12766.     declare @subid  uniqueidentifier
  12767.     declare @job_id uniqueidentifier
  12768.     set nocount on
  12769.  
  12770.     select @owner_sid = NULL
  12771.  
  12772.     if exists (select * from sysobjects 
  12773.                where type = 'U' and
  12774.                      name = 'sysmergesubscriptions')
  12775.         -- Get the server id of the current server (subscriber)
  12776.     begin
  12777.         -- Get the srvid of the current subscriber database 
  12778.         select @srvid = srvid 
  12779.         from master.dbo.sysservers      
  12780.         where upper(@@servername) = upper(srvname) collate database_default
  12781.  
  12782.         -- Get the pubid from sysmergepublications using @publisher, 
  12783.         -- @publisher_db, @publication 
  12784.         select @pubid = pubid
  12785.         from sysmergepublications
  12786.         where @publication = name
  12787.  
  12788.         -- Get the subid from sysmergesubscriptions using @pubid and @srvid
  12789.         select @subid = subid
  12790.         from sysmergesubscriptions
  12791.         where @pubid = pubid and
  12792.               @srvid = srvid and
  12793.               pubid <> subid 
  12794.  
  12795.         -- Get the merge_jobid from MSreplication_info using @subid
  12796.         select @job_id = merge_jobid
  12797.         from MSmerge_replinfo
  12798.         where @subid = repid
  12799.  
  12800.         -- Finally, get the owner_sid from msdb..sysjobs using @job_id
  12801.         select @owner_sid = owner_sid
  12802.         from msdb..sysjobs 
  12803.         where @job_id = job_id
  12804.     end
  12805. go
  12806.  
  12807. exec dbo.sp_MS_marksystemobject 'sp_MSget_mergepullsubsagent_owner'
  12808.  
  12809. raiserror('Creating procedure sp_dropmergepullsubscription', 0,1)
  12810. GO
  12811. CREATE PROCEDURE sp_dropmergepullsubscription(
  12812.     @publication         sysname = NULL,                  /* Publication name */
  12813.     @publisher            sysname = NULL,              /* Publisher server */
  12814.     @publisher_db        sysname = NULL,              /* Publication database */
  12815.     @reserved            bit = 0
  12816.     )AS
  12817.  
  12818.     SET NOCOUNT ON
  12819.  
  12820.     /*
  12821.     ** Declarations.
  12822.     */
  12823.  
  12824.     declare @retcode                 int
  12825.     declare @subscriber_srvid         int
  12826.     declare @publisher_srvid         int
  12827.     declare    @pubid                     uniqueidentifier
  12828.     declare    @subid                     uniqueidentifier
  12829.     declare    @partnerid                 uniqueidentifier 
  12830.     declare @local_server            sysname
  12831.     declare @local_db                sysname
  12832.     declare @merge_jobid             binary(16)
  12833.     declare @cmd                     nvarchar(255)
  12834.     declare @pubidstr                nvarchar(38)
  12835.     declare @subscriber                sysname
  12836.     declare @subscriber_db            sysname
  12837.     declare @subscriber_type        int
  12838.     declare @local_job                 bit
  12839.     declare @implicit_transaction    int
  12840.     declare @close_cursor_at_commit int
  12841.     declare @owner_sid              varbinary(85)
  12842.     declare @owner_name             sysname
  12843.     declare @qualified_publication_name nvarchar(512)
  12844.  
  12845.  
  12846.     select @close_cursor_at_commit = 0
  12847.     select @implicit_transaction = 0
  12848.  
  12849.     /*
  12850.     ** Get original setting values before setting them to false for recursive calling
  12851.     */
  12852.     IF (@reserved = 0)
  12853.     BEGIN
  12854.         SELECT @implicit_transaction = @@options & 2
  12855.         SELECT @close_cursor_at_commit = @@options & 4
  12856.         SET IMPLICIT_TRANSACTIONS OFF
  12857.         SET CURSOR_CLOSE_ON_COMMIT OFF
  12858.     END
  12859.  
  12860.     /* 
  12861.     ** Security Check.
  12862.     */
  12863.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  12864.     if @@ERROR <> 0 or @retcode <> 0
  12865.         return(1)
  12866.  
  12867.      /*
  12868.     ** Initializations.
  12869.     */                
  12870.     set @local_db = DB_NAME()
  12871.     set @local_server = @@SERVERNAME
  12872.     set @subscriber = @@SERVERNAME     
  12873.     set @subscriber_db = DB_NAME()
  12874.  
  12875.    /*
  12876.     ** Assign parameter values appropriately
  12877.     */
  12878.             
  12879.     select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  12880.     IF @subscriber_srvid IS NULL
  12881.         BEGIN
  12882.            RAISERROR (14010, 16, -1)
  12883.            RETURN (1)     
  12884.         END
  12885.         
  12886.     IF not exists (select name from sysobjects where name='sysmergesubscriptions')
  12887.         BEGIN
  12888.             RAISERROR (14055, 16, -1)
  12889.             RETURN (1)
  12890.         END        
  12891.  
  12892.     /*
  12893.     ** Parameter Check: @publisher
  12894.     ** Check to make sure that the publisher is defined
  12895.     */
  12896.             IF @publisher IS NULL
  12897.             BEGIN
  12898.                 RAISERROR (14043, 16, -1, '@publisher')
  12899.                 RETURN (1)
  12900.             END
  12901.  
  12902.             EXECUTE @retcode = dbo.sp_validname @publisher
  12903.             IF @@ERROR <> 0 OR @retcode <> 0
  12904.                RETURN (1)
  12905.  
  12906.     /*
  12907.     ** Parameter Check: @publisher_db
  12908.     */
  12909.             IF @publisher_db IS NULL
  12910.             BEGIN
  12911.                 RAISERROR (14043, 16, -1, '@publisher_db')
  12912.                 RETURN (1)
  12913.             END    
  12914.  
  12915.     /*
  12916.     ** Parameter Check:  @publication.
  12917.     ** If the publication name is specified, check to make sure that it
  12918.     ** conforms to the rules for identifiers and that the publication
  12919.     ** actually exists.  Disallow NULL.
  12920.     */
  12921.     if @publication IS NULL
  12922.         BEGIN
  12923.             RAISERROR (14043, 16, -1, '@publication')
  12924.             RETURN (1)
  12925.         END
  12926.  
  12927.     IF LOWER(@publication) = 'all'
  12928.         BEGIN
  12929.             declare hC1 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT name FROM sysmergepublications FOR READ ONLY
  12930.             
  12931.             OPEN hC1
  12932.             FETCH hC1 INTO @publication
  12933.             if @@fetch_status = -1 
  12934.                 begin
  12935.                     CLOSE hC1
  12936.                     DEALLOCATE hC1
  12937.                     RETURN (0) --- It's OK to have no publication when 'ALL'
  12938.                 end
  12939.             WHILE (@@fetch_status <> -1)
  12940.                 BEGIN
  12941.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  12942.                                       @publisher = @publisher,
  12943.                                       @publisher_db = @publisher_db,
  12944.                                       @reserved = 1
  12945.                     FETCH hC1 INTO @publication
  12946.                 END
  12947.             CLOSE hC1
  12948.             DEALLOCATE hC1
  12949.             RETURN (0)
  12950.         END
  12951.         
  12952.     IF LOWER(@publisher) = 'all'
  12953.         BEGIN
  12954.             declare hC4 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT srvname FROM master..sysservers FOR READ ONLY
  12955.             
  12956.             OPEN hC4
  12957.             FETCH hC4 INTO @publisher
  12958.             WHILE (@@fetch_status <> -1)
  12959.                 BEGIN
  12960.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  12961.                                                 @publisher = @publisher,
  12962.                                                 @publisher_db = @publisher_db,
  12963.                                                 @reserved = 1
  12964.                     FETCH hC4 INTO @publisher
  12965.                 END
  12966.             CLOSE hC4
  12967.             DEALLOCATE hC4
  12968.             RETURN (0)
  12969.         END
  12970.  
  12971.     /*
  12972.     ** Validate that the publisher is a valid server
  12973.     */
  12974.     select @publisher_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@publisher) collate database_default
  12975.     IF @publisher_srvid IS NULL
  12976.         BEGIN
  12977.             --RAISERROR (14010, 16, -1)
  12978.                RETURN (1)
  12979.         END
  12980.  
  12981.  
  12982.     /* Previously the condition is set as 'AND subid<>pubid' which is fatally errorous */
  12983.  
  12984.     IF LOWER(@publisher_db) = 'all'
  12985.         BEGIN
  12986.             declare hC5 CURSOR LOCAL FAST_FORWARD FOR select DISTINCT db_name FROM sysmergesubscriptions 
  12987.                     WHERE subid = pubid and pubid in (select pubid from sysmergepublications 
  12988.                             where UPPER(publisher)=UPPER(@publisher) 
  12989.                                 and name=@publication)
  12990.                                 
  12991.                         FOR READ ONLY
  12992.             
  12993.             OPEN hC5
  12994.             FETCH hC5 INTO @publisher_db
  12995.             WHILE (@@fetch_status <> -1)
  12996.                 BEGIN
  12997.                     EXECUTE dbo.sp_dropmergepullsubscription @publication = @publication,
  12998.                                       @publisher = @publisher,
  12999.                                       @publisher_db = @publisher_db,
  13000.                                       @reserved = 1
  13001.                     FETCH hC5 INTO @publisher_db
  13002.                 END
  13003.             CLOSE hC5
  13004.             DEALLOCATE hC5
  13005.             RETURN (0)
  13006.         END
  13007.  
  13008.     /*
  13009.     ** return error if only there is no 'ALL'. Same is true for the rest of error handling.
  13010.     */
  13011.     if NOT EXISTS (select * FROM sysmergepublications 
  13012.     WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db) 
  13013.     BEGIN
  13014.         if @reserved = 0
  13015.             RAISERROR (20026, 16, -1, @publication)
  13016.         RETURN (1)
  13017.     END
  13018.         
  13019.     select @pubid = pubid from sysmergepublications where name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  13020.     set @pubidstr = '''' + convert(nchar(36), @pubid) + ''''
  13021.     if @pubid is null  
  13022.         BEGIN
  13023.             if @reserved = 0
  13024.                 RAISERROR (20026, 16, -1, @publication)
  13025.                RETURN (1)
  13026.         END
  13027.  
  13028.     /*
  13029.     ** Only members of the sysadmin group and the creator of the distribution
  13030.     ** agent can drop a pull subscription successfully. This behavior matches 
  13031.     ** the behavior of the sysjobs_view. DBO of the subscriber database, 
  13032.     ** sysadmins (owner is undefined) can drop a subscription if the owner_sid 
  13033.     ** is null.
  13034.     */
  13035.     
  13036.     EXEC sp_MSget_mergepullsubsagent_owner @publisher = @publisher,
  13037.                                            @publisher_db = @publisher_db,
  13038.                                            @publication = @publication,
  13039.                                            @owner_sid = @owner_sid OUTPUT 
  13040.     
  13041.     IF (@owner_sid is not null AND
  13042.         (SUSER_SID() <> @owner_sid) AND
  13043.         (ISNULL(IS_SRVROLEMEMBER('sysadmin'),0) = 0))
  13044.     BEGIN
  13045.         SELECT @owner_name = SUSER_SNAME(@owner_sid)
  13046.         SELECT @qualified_publication_name = @publisher + N':' + 
  13047.                                              @publisher_db + N':' +
  13048.                                              @publication
  13049.         RAISERROR(21121,16,-1,@owner_name, @qualified_publication_name) 
  13050.         RETURN (1)
  13051.     END
  13052.  
  13053.     /*
  13054.     ** Get subscriptions from either local replicas or global replicas
  13055.     */
  13056.     select @subid = subs1.subid, @subscriber_type = subs1.subscriber_type, @partnerid = subs2.subid from
  13057.         sysmergesubscriptions     subs1,
  13058.           sysmergesubscriptions     subs2,
  13059.         sysmergepublications         pubs
  13060.         where subs1.srvid = @subscriber_srvid
  13061.             and subs1.db_name = @subscriber_db
  13062.             and subs2.srvid = @publisher_srvid
  13063.             and subs2.db_name = @publisher_db
  13064.             and subs1.pubid = subs2.subid
  13065.             and subs2.pubid = pubs.pubid
  13066.             and pubs.name = @publication
  13067.             and UPPER(pubs.publisher)=UPPER(@publisher)
  13068.             and pubs.publisher_db=@publisher_db
  13069.  
  13070.     if @subid IS NULL 
  13071.          begin
  13072.             if @reserved = 0 
  13073.                 raiserror (14050, 16, -1)
  13074.              RETURN (0)
  13075.         end                 
  13076.  
  13077.     begin tran
  13078.     save TRAN dropmergepullsubscription
  13079.     
  13080.         /*     
  13081.         ** Drop the local merge task
  13082.         */
  13083.         select @merge_jobid = merge_jobid from MSmerge_replinfo WHERE repid = @subid
  13084.         if (@merge_jobid IS NOT NULL)
  13085.         BEGIN
  13086.             IF EXISTS (SELECT * FROM msdb..sysjobs_view WHERE job_id = @merge_jobid)
  13087.             BEGIN
  13088.                 EXEC @retcode = msdb.dbo.sp_delete_job @job_id = @merge_jobid
  13089.                 IF @@ERROR <> 0 or @retcode <> 0
  13090.                     GOTO FAILURE
  13091.             END
  13092.         END                                    
  13093.  
  13094.         if @subid <> @partnerid
  13095.         BEGIN
  13096.             DELETE MSmerge_replinfo WHERE repid = @subid 
  13097.             IF @@ERROR <> 0
  13098.                 GOTO FAILURE
  13099.             delete from sysmergesubscriptions where subid = @subid
  13100.             if @@ERROR <> 0
  13101.                 GOTO FAILURE
  13102.  
  13103.             /* Call sp_MSunregistersubscription so that the reg entries get deleted */
  13104.             exec @retcode = dbo.sp_MSunregistersubscription @publisher = @publisher,
  13105.                                         @publisher_db = @publisher_db,
  13106.                                         @publication = @publication,
  13107.                                         @subscriber = @@SERVERNAME,
  13108.                                         @subscriber_db = @subscriber_db
  13109.             IF @retcode<>0 or @@ERROR<>0
  13110.                 GOTO FAILURE
  13111.  
  13112.             exec dbo.sp_MSpublicationcleanup @publisher=@publisher, 
  13113.                                             @publisher_db = @publisher_db,
  13114.                                             @publication = @publication
  13115.             IF @@ERROR <> 0 
  13116.                 BEGIN
  13117.                     RAISERROR (20025, 16, -1, @publication)
  13118.                     GOTO FAILURE
  13119.                 END
  13120.         END
  13121.         
  13122.         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsubscription_properties')
  13123.         BEGIN
  13124.             DELETE FROM MSsubscription_properties 
  13125.             WHERE UPPER(publisher) = UPPER(@publisher)    AND
  13126.             publisher_db  = @publisher_db AND
  13127.             publication = @publication 
  13128.     
  13129.             IF @@ERROR <> 0 
  13130.                 GOTO FAILURE
  13131.     
  13132.             IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  13133.             BEGIN
  13134.                 exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  13135.                 IF @@ERROR <> 0 or @retcode <> 0
  13136.                     GOTO FAILURE
  13137.             END
  13138.         END
  13139.  
  13140.     COMMIT TRAN
  13141.     /*
  13142.     ** Set back original settings
  13143.     */
  13144.     IF @reserved = 0
  13145.     BEGIN
  13146.         /* 
  13147.         ** If last subscription is dropped and the DB is not enabled for publishing,
  13148.         ** then remove the merge system tables
  13149.         */
  13150.         IF (not exists (select * from sysmergesubscriptions )) 
  13151.             AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME())=0
  13152.         BEGIN
  13153.                 execute @retcode = dbo.sp_MSdrop_mergesystables
  13154.                 if @@ERROR <> 0 or @retcode <> 0
  13155.                     begin
  13156.                         return (1)
  13157.                     end
  13158.         END    
  13159.  
  13160.         IF @implicit_transaction <>0 
  13161.             SET IMPLICIT_TRANSACTIONS ON
  13162.         IF @close_cursor_at_commit <>0 
  13163.             SET CURSOR_CLOSE_ON_COMMIT ON
  13164.     END
  13165.  
  13166.     RETURN(0)        
  13167.  
  13168. FAILURE:
  13169.     RAISERROR (14056, 16, -1)
  13170.     if @@trancount > 0
  13171.     begin
  13172.         ROLLBACK TRANSACTION dropmergepullsubscription
  13173.         COMMIT TRANSACTION
  13174.     end
  13175.     /*
  13176.     ** Set back original settings
  13177.     */    
  13178.     IF @reserved = 0
  13179.     BEGIN
  13180.         IF @implicit_transaction <>0 
  13181.             SET IMPLICIT_TRANSACTIONS ON
  13182.         IF @close_cursor_at_commit <>0 
  13183.             SET CURSOR_CLOSE_ON_COMMIT ON
  13184.     END
  13185.     return 1
  13186. go
  13187. exec dbo.sp_MS_marksystemobject sp_dropmergepullsubscription
  13188. go
  13189.  
  13190. grant execute on dbo.sp_dropmergepullsubscription to public
  13191. go
  13192.  
  13193. -- synctran supporting sprocs
  13194. raiserror('Creating procedure sp_MSreplraiserror', 0,1)
  13195. go
  13196.  
  13197. create proc sp_MSreplraiserror @errorid int, @param1 sysname = null, @param2 sysname= null
  13198. as
  13199.     if @errorid = 20508 raiserror (20508, 16, 1)
  13200.     else if @errorid = 20509 raiserror (20509, 16, 1)
  13201.     else if @errorid = 20510 raiserror (20510, 16, 1)
  13202.     else if @errorid = 20511 raiserror (20511, 16, 1)
  13203.     else if @errorid = 20512 raiserror (20512, 16, 1)
  13204.     else if @errorid = 20515 raiserror (20515, 16, 1)
  13205.     else if @errorid = 20516 raiserror (20516, 16, 1)
  13206.     else if @errorid = 20517 raiserror (20517, 16, 1)
  13207.     else if @errorid = 20518 raiserror (20518, 16, 1)
  13208.     else if @errorid = 20519 raiserror (20519, 16, 1)
  13209.     else if @errorid = 20520 raiserror (20520, 16, 1)
  13210.     else if @errorid = 21034 raiserror (21034, 16, 1)
  13211.     else if @errorid = 21052 raiserror (21052, 16, 1)
  13212.     else if @errorid = 21054 raiserror (21054, 16, 1)
  13213.     else if @errorid = 21064 raiserror (21064, 16, 1)
  13214.     else if @errorid = 21161 raiserror (21161, 16, 1)
  13215.     else if @errorid = 20598 raiserror (20598, 16, 1)
  13216. go
  13217.  
  13218. raiserror('Creating procedure sp_check_sync_trigger', 0,1)
  13219. go
  13220.  
  13221. create proc sp_check_sync_trigger @trigger_procid int, @trigger_op char(10) OUTPUT
  13222. as
  13223.  
  13224.     select @trigger_op = NULL
  13225.  
  13226. -- debug
  13227. --    select 'Entered sp_check_synctrigger', 'calling trigger' = object_name(@trigger_procid)
  13228. -- debug
  13229.  
  13230.     declare @trigid int
  13231.  
  13232.     select @trigid = so1.id from sysobjects so1, sysobjects so2 where
  13233.     so1.type = N'TR' and so1.name like N'trg_MSsync_ins_%' and so1.parent_obj = so2.parent_obj
  13234.     and so2.id = @trigger_procid
  13235.     
  13236.     -- if nestlevel of insert trigger on same table > 0 then bail
  13237.  
  13238.     if trigger_nestlevel( @trigid ) > 0
  13239.     begin
  13240. -- debug
  13241. --        select 'sp_check_synctrigger: synctran insert trigger is active, so do nothing'
  13242. -- debug
  13243.          return 1
  13244.     end
  13245.     else
  13246.         return 0
  13247. go
  13248.  
  13249. raiserror('Creating procedure sp_check_for_sync_trigger', 0,1)
  13250. go
  13251.  
  13252. create proc sp_check_for_sync_trigger @tabid int, @trigger_op char(10) = NULL OUTPUT
  13253. as
  13254.  
  13255.     select @trigger_op = NULL
  13256.  
  13257. -- debug
  13258. --    select 'Entered sp_check_for_sync_trigger', 'calling trigger' = object_name(@trigger_procid)
  13259. -- debug
  13260.  
  13261.     declare @ins_trigid int
  13262.     declare @upd_trigid int
  13263.     declare @del_trigid int
  13264.  
  13265.     select @ins_trigid = id from sysobjects where
  13266.         type = N'TR' and name like N'trg_MSsync_ins_%' and parent_obj = @tabid
  13267.     select @upd_trigid = id from sysobjects where
  13268.         type = N'TR' and name like N'trg_MSsync_upd_%' and parent_obj = @tabid
  13269.     select @del_trigid = id from sysobjects where
  13270.         type = N'TR' and name like N'trg_MSsync_del_%' and parent_obj = @tabid
  13271.  
  13272.     if trigger_nestlevel( @ins_trigid ) > 0
  13273.     begin
  13274. -- debug
  13275. --     select 'sp_check_for_sync_trigger: synctran insert trigger is active'
  13276. -- debug
  13277.          select @trigger_op = 'ins'
  13278.          return 1
  13279.     end
  13280.     else    -- if nestlevel of insert trigger on same table > 0 then bail
  13281.     if trigger_nestlevel( @upd_trigid ) > 0
  13282.     begin
  13283. -- debug
  13284. --     select 'sp_check_for_sync_trigger: synctran update trigger is active'
  13285. -- debug
  13286.          select @trigger_op = 'upd'
  13287.          return 1
  13288.     end
  13289.     else
  13290.     if trigger_nestlevel( @del_trigid ) > 0
  13291.     begin
  13292. -- debug
  13293. --     select 'sp_check_for_sync_trigger: synctran update trigger is active'
  13294. -- debug
  13295.          select @trigger_op = 'del'
  13296.          return 1
  13297.     end
  13298.     else
  13299.         return 0
  13300. go
  13301.  
  13302. raiserror('Creating procedure sp_MSpad_command', 0,1)
  13303. go
  13304. create proc sp_MSpad_command (
  13305.     @cmd     nvarchar(4000) output,
  13306.     @indent  int = 0)  -- indent for command buffer (for pretty formatting
  13307. as
  13308. BEGIN
  13309.     declare
  13310.         @cnt int
  13311.         ,@num_tabs int
  13312.         ,@num_spaces int
  13313.  
  13314.     select @cmd = N''
  13315.     select @num_tabs = @indent / 4
  13316.     select @num_spaces = @indent % 4
  13317.  
  13318.     select @cnt = 0
  13319.     while (@cnt < @num_tabs)
  13320.     begin
  13321.         select @cmd = @cmd + N'    '
  13322.         select @cnt = @cnt + 1
  13323.     end
  13324.  
  13325.     select @cnt = 0
  13326.     while (@cnt < @num_spaces)
  13327.     begin
  13328.         select @cmd = @cmd + N' '
  13329.         select @cnt = @cnt + 1
  13330.     end
  13331. END
  13332. go
  13333.  
  13334. raiserror('Creating procedure sp_MSflush_command', 0,1)
  13335. go
  13336. create proc sp_MSflush_command
  13337.     @cmd     nvarchar(4000) output,
  13338.     @force   int,     -- 0 = flush if necesssary, 1 = flush always
  13339.     @indent  int = 0  -- indent for command buffer (for pretty formatting
  13340. as
  13341. -- debug
  13342. --    if len(@cmd) >= 4000
  13343. --    begin
  13344. --        raiserror("buffer overflow!", 16, 1)
  13345. --        select @cmd
  13346. --    end
  13347. -- debug
  13348.  
  13349.     if @force = 1 or len( @cmd ) > 3000
  13350.     begin
  13351.         insert into #proctext(procedure_text) values( @cmd )
  13352.         select @cmd = N''
  13353.         if @indent > 0 
  13354.             exec dbo.sp_MSpad_command @cmd output, @indent
  13355.     end
  13356. go
  13357.  
  13358.  
  13359.  
  13360. raiserror('Creating procedure sp_MSget_colinfo', 0,1)
  13361. go
  13362. create proc sp_MSget_colinfo 
  13363.     @objid int,
  13364.     @colid int, 
  13365.     @columns binary(32), 
  13366.     @bGetTextImageInfo tinyint = 0, -- boolean for returning text/image info
  13367.     @colname sysname output, 
  13368.     @ccoltype sysname = null output
  13369. as
  13370.     declare @isset        int
  13371.  
  13372.     if @columns is not NULL
  13373.         -- this code path for synctran procs
  13374.         exec @isset = dbo.sp_isarticlecolbitset @colid, @columns
  13375.     else
  13376.         -- this code path for synctran triggers
  13377.         select @isset = 1
  13378.  
  13379.     if @isset != 0 
  13380.     begin
  13381.         select @colname = c.name, @ccoltype= t.name from syscolumns c, systypes t
  13382.         where id = @objid and colid = @colid and c.xtype = t.xusertype
  13383.         -- when checking replicated columns, text/image datatypes cannot be declared or used locally
  13384.         if (@bGetTextImageInfo = 0) and (@ccoltype in (N'text',N'ntext',N'image'))
  13385.             return 1
  13386.     end
  13387.     else
  13388.     begin
  13389.         select @colname = null, @ccoltype = null
  13390.         return 1
  13391.     end
  13392.  
  13393.     return 0
  13394. go
  13395.  
  13396. raiserror('Creating procedure sp_MSget_col_position ', 0,1)
  13397. go
  13398. create procedure sp_MSget_col_position (
  13399.     @objid int,
  13400.     @columns binary(32),
  13401.     @key     sysname, 
  13402.     @colpos  sysname = NULL output,
  13403.     @art_col int = NULL output,
  13404.     @get_num_col bit = 0,
  13405.     @num_col  int = NULL output,
  13406.     @this_col int = null output
  13407. )
  13408. as
  13409. BEGIN  
  13410.     declare @colname      sysname
  13411.             ,@ccoltype     sysname
  13412.             ,@src_cols     int
  13413.             ,@rc           int
  13414.     
  13415.     select @src_cols = max(colid) from syscolumns where id = @objid
  13416.     select @this_col = 1
  13417.             ,@num_col = 0
  13418.  
  13419.     while @this_col <= @src_cols 
  13420.     begin
  13421.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 1, @colname output, @ccoltype output
  13422.         if @rc = 0
  13423.         begin
  13424.             select @num_col = @num_col + 1
  13425.             -- If @get_num_col is 1, we just need the number of columns in the partition.
  13426.             if (@get_num_col = 0) and (@colname = @key)
  13427.             begin
  13428.                 select @colpos = 'c' + convert(varchar(4), @this_col)
  13429.                         ,@art_col = @num_col
  13430.                 break
  13431.             end
  13432.         end
  13433.         select @this_col = @this_col + 1
  13434.     end
  13435.     return 0
  13436. END
  13437. go
  13438.  
  13439. raiserror('Creating procedure sp_MSget_map_position ', 0,1)
  13440. go
  13441. create procedure sp_MSget_map_position 
  13442.     @primary_key_bitmap varbinary(4000) = null,
  13443.     @index int,
  13444.     @colpos  sysname = NULL output,
  13445.     @art_col int = NULL output
  13446. as
  13447.   
  13448.     declare @this_col int
  13449.     declare @num_keys int
  13450.     declare @num_cols int
  13451.     
  13452.     select @this_col = 1
  13453.     select @num_keys = 0
  13454.     select @num_cols = datalength(@primary_key_bitmap) * 8
  13455.  
  13456.     select @colpos = null
  13457.     select @art_col = null
  13458.  
  13459.     while @this_col <= @num_cols
  13460.     begin
  13461.         if (substring(@primary_key_bitmap, 1 + (@this_col-1) / 8 , 1) &
  13462.             power(2, (@this_col-1) % 8 )) <> 0
  13463.         begin
  13464.             select @num_keys = @num_keys + 1
  13465.             if @num_keys = @index
  13466.             begin
  13467.                 select @art_col = @this_col
  13468.                 select @colpos = 'c' + convert(sysname, @this_col)                
  13469.                 break
  13470.             end
  13471.         end
  13472.         select @this_col = @this_col + 1
  13473.     end
  13474. go
  13475.  
  13476. exec dbo.sp_MS_marksystemobject sp_MSget_map_position
  13477. go
  13478.  
  13479. raiserror('Creating procedure sp_MSget_type', 0,1)
  13480. go
  13481. create proc sp_MSget_type 
  13482.     @tabid int, 
  13483.     @colid int, 
  13484.     @colname sysname output, 
  13485.     @typestring nvarchar(4000) output
  13486. as
  13487.     declare @ccolchar       nvarchar(5)
  13488.     declare @coltype        tinyint
  13489.     declare @prec           smallint
  13490.     declare @scale          int
  13491.     declare @ccoltype       sysname
  13492.     declare @xtype          int
  13493.  
  13494.     select @colname = c.name, @xtype = c.xtype, @prec = c.prec, @scale = c.scale,
  13495.         @ccoltype = t.name
  13496.     from syscolumns c, systypes t
  13497.     where c.id = @tabid and c.colid = @colid and 
  13498.         c.xtype = t.xusertype
  13499.      
  13500.     select @typestring = @ccoltype
  13501.  
  13502.     -- datatypes requiring precision (nchar, nvarchar, binary, varbinary)
  13503.     -- format: @var <dt> (prec)
  13504.     if @ccoltype in (N'char',N'nchar', N'varchar', N'nvarchar', N'binary', N'varbinary') 
  13505.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),@prec)) + N')'
  13506.  
  13507.     -- datatypes requiring precision & scale (numeric & decimal)
  13508.     -- format: @var <dt> (prec, scale)
  13509.     else if @ccoltype in (N'numeric', N'decimal') 
  13510.         select @typestring = @typestring + N'(' + rtrim(convert(nchar(10),ColumnProperty(@tabid, @colname, 'PRECISION'))) + N',' + 
  13511.             rtrim(convert(nchar(10),@scale)) + N')'
  13512.     
  13513.     -- text/image datatypes cannot be declared or used locally
  13514.     else if @ccoltype in (N'text',N'ntext',N'image')
  13515.         select  @typestring = NULL
  13516. go
  13517.  
  13518. raiserror('Creating procedure sp_MSscript_where_clause', 0,1)
  13519. go
  13520. create procedure sp_MSscript_where_clause (
  13521.     @objid          int,
  13522.     @columns      binary(32), 
  13523.     @clause_type  varchar(15) = 'pk_new', -- 'new pk', 'old pk', 'upd version', 'upd rc', 'trg pk', 'qcft_comp', 'new_pk_q', 'subwins_check'
  13524.     @ts_col       sysname = NULL,
  13525.     @indent       int = 0,
  13526.     @op_type      char(3) = NULL, -- 'ins', 'del', 'upd'
  13527.     @primary_key_bitmap varbinary(4000) = null )
  13528. as
  13529. BEGIN
  13530.     declare    @cmd            nvarchar(4000)
  13531.             ,@colname        sysname
  13532.             ,@ccoltype        sysname
  13533.             ,@spacer        nvarchar(20)
  13534.             ,@indkey        int
  13535.             ,@indid            int
  13536.             ,@key            sysname
  13537.             ,@rc            int
  13538.             ,@this_col        int
  13539.             ,@art_col        int
  13540.             ,@src_cols        int
  13541.             ,@total_col        int
  13542.             ,@col            sysname
  13543.             ,@qualname        nvarchar(512)
  13544.             ,@curparam        nvarchar(20)
  13545.             ,@retcode        int
  13546.             ,@fcreatedcolmap    bit
  13547.     declare @colmap table (relativeorder int identity(1,1), colid int)
  13548.  
  13549.     select @spacer = N' '
  13550.         ,@cmd = N''
  13551.         ,@indkey = 1
  13552.         ,@indid = 0
  13553.         ,@fcreatedcolmap = 0
  13554.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  13555.     select @src_cols = max(colid)
  13556.             ,@total_col = count(colid)
  13557.         from syscolumns where id = @objid
  13558.     exec dbo.sp_MSpad_command @cmd output, @indent
  13559.     if (@clause_type = 'qcft_comp')
  13560.         select @cmd = @cmd + N' '' where '
  13561.     else
  13562.         select @cmd = @cmd + N'where'
  13563.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  13564.  
  13565.     if @clause_type in ('new pk','old pk','upd version','trg pk','version pk','qcft_comp','new_pk_q','subwins_check')
  13566.     begin
  13567.         if @primary_key_bitmap is null
  13568.         begin
  13569.             exec @indid = dbo.sp_MStable_has_unique_index @objid
  13570.             if @indid is null
  13571.             begin
  13572.                 raiserror('Debug: Cannot find unique index', 16, -1)
  13573.                 return (1)
  13574.             end
  13575.         end
  13576.  
  13577.         --
  13578.         -- check if column Id match relative column order
  13579.         -- for specific trigger operations
  13580.         --
  13581.         if ((@total_col < @src_cols) and (@clause_type = 'trg pk') and 
  13582.             (@columns is null) and (@primary_key_bitmap is not null))
  13583.         begin
  13584.             --
  13585.             -- this table may have altered columns, so when we need to 
  13586.             -- set a mapping for using the bitmaps properly as the bitmap
  13587.             -- always refers relative column order
  13588.             --
  13589.             insert into @colmap (colid)
  13590.                 select colid from syscolumns where id = @objid order by colid
  13591.             if (@@error != 0)
  13592.             begin
  13593.                 raiserror('Could not create column mapping', 16, -1)
  13594.                 return (1)
  13595.             end
  13596.             select @fcreatedcolmap = 1
  13597.         end
  13598.         
  13599.         while (1=1)
  13600.         begin
  13601.             --
  13602.             -- get the column position
  13603.             --
  13604.                 if @primary_key_bitmap is null 
  13605.                 begin
  13606.                          select @key = index_col(@qualname, @indid, @indkey)
  13607.                          if @key is null
  13608.                              break
  13609.                          --exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, @this_col output
  13610.                          exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, NULL, 0, NULL, @this_col output
  13611.                 end
  13612.                 else
  13613.                 begin
  13614.                     exec dbo.sp_MSget_map_position @primary_key_bitmap, @indkey, @col output, @this_col output
  13615.                     if @this_col is null
  13616.                         break
  13617.  
  13618.                 --
  13619.                 -- set the actual column id for this relative order in the PK bitmap if necessary
  13620.                 --
  13621.                 if (@fcreatedcolmap = 1)
  13622.                 begin
  13623.                     select @this_col = colid
  13624.                         ,@col = 'c' + convert(sysname, colid) 
  13625.                     from @colmap 
  13626.                     where relativeorder = @this_col 
  13627.                 end
  13628.                 end
  13629.  
  13630.             --
  13631.             -- Get column name
  13632.             --
  13633.             exec @retcode = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @key output, @ccoltype output
  13634.             if (@retcode = 1)
  13635.             begin
  13636.                 --
  13637.                 -- this column not used for replication
  13638.                 -- continue
  13639.                 --
  13640.                 select @indkey = @indkey + 1
  13641.                 continue
  13642.             end
  13643.         
  13644.             if @clause_type = 'new pk'
  13645.             begin
  13646.                 if ColumnProperty(@objid, @key, 'IsIdentity') = 1
  13647.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @@identity'
  13648.                 else
  13649.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  13650.  
  13651.                 select @spacer = ' and '
  13652.             end
  13653.             else if @clause_type in ('upd version', 'subwins_check')
  13654.             begin
  13655.                 select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  13656.                 select @spacer = ' and '
  13657.             end
  13658.             else if @clause_type = 'version pk'
  13659.             begin
  13660.                 select @cmd = @cmd + @spacer + @qualname + '.' + quotename(@key) + N' = inserted.' + quotename(@key)
  13661.                 select @spacer = ' and
  13662.     '
  13663.             end
  13664.             else if @clause_type in ('trg pk', 'old pk')
  13665.             begin                
  13666.                 if @op_type = 'ins'
  13667.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col + N'_old'
  13668.                 else
  13669.                     -- The vars correspoding to pk were set in sp_MSscript
  13670.                     -- _pkvar_assignment.
  13671.                     select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col 
  13672.                 select @spacer = ' and
  13673.     '
  13674.             end
  13675.             else if (@clause_type = 'qcft_comp')
  13676.             begin
  13677.                 --
  13678.                 -- Conflict compensation generation
  13679.                 -- This is a special case - we generate
  13680.                 -- and exec string for the WHERE clause
  13681.                 --
  13682.                 if (@op_type = 'ins')
  13683.                     select @curparam = N'@' + @col
  13684.                 else if (@op_type = 'del')
  13685.                     select @curparam = N'@' + @col + N'_old'
  13686.                 else
  13687.                     select @curparam = N'ISNULL(@' + @col + N', @' + @col + N'_old)'
  13688.                 
  13689.                 select @cmd = @cmd + @spacer + quotename(@key)
  13690.                 
  13691.                 if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'varchar')
  13692.                     select @cmd = @cmd + N' = '' + '''''''' + master.dbo.fn_MSgensqescstr(' + @curparam + N') collate database_default + '''''''' '
  13693.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'nvarchar')
  13694.                     select @cmd = @cmd + N' = '' + ''N'''''' + master.dbo.fn_MSgensqescstr(' + @curparam + N') collate database_default + '''''''' '
  13695.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'char')
  13696.                     select @cmd = @cmd + N' = '' + '''''''' + master.dbo.fn_MSgensqescstr(CAST(RTRIM(' + @curparam + N') as nvarchar)) collate database_default + '''''''' '
  13697.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'nchar')
  13698.                     select @cmd = @cmd + N' = '' + ''N'''''' + master.dbo.fn_MSgensqescstr(CAST(RTRIM(' + @curparam + N') as nvarchar)) collate database_default + '''''''' '
  13699.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('binary','varbinary'))
  13700.                     select @cmd = @cmd + N' = '' + master.dbo.fn_varbintohexstr(' + @curparam + N') collate database_default ' 
  13701.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('bit','bigint','int','smallint','tinyint','float','real','decimal','numeric'))
  13702.                     select @cmd = @cmd + N' = '' + CAST(' + @curparam + N' as nvarchar) '
  13703.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('money','smallmoney'))
  13704.                     select @cmd = @cmd + N' = '' + CONVERT(nvarchar(40),' + @curparam + N', 2) '
  13705.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'uniqueidentifier')
  13706.                     select @cmd = @cmd + N' = '' + '''''''' + CAST(' + @curparam + N' as nvarchar(40)) + '''''''' '
  13707.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) in ('datetime','smalldatetime'))
  13708.                     select @cmd = @cmd + N' = '' + '''''''' + CONVERT(nvarchar(40), ' + @curparam + N', 112) + N'' '' + CONVERT(nvarchar(40), ' + @curparam + N', 114) + '''''''' '    
  13709.                 else if (lower(@ccoltype collate SQL_Latin1_General_CP1_CS_AS) = 'sql_variant')
  13710.                     select @cmd = @cmd + N' = '' + master.dbo.fn_sqlvarbasetostr(' + @curparam + N' ) collate database_default '
  13711.                 else
  13712.                     select @cmd = @cmd + N' = '' + CAST(' + @curparam + N' as nvarchar) '
  13713.                 
  13714.                 select @spacer = ' + '' and  '
  13715.             end
  13716.             else if @clause_type = 'new_pk_q'
  13717.             begin
  13718.                 --
  13719.                 -- new value of primary key, ignore identity
  13720.                 -- used for scripting in synctran procs
  13721.                 --
  13722.                 select @cmd = @cmd + @spacer + quotename(@key) + N' = @' + @col
  13723.                 select @spacer = ' and '
  13724.             end
  13725.             select @indkey = @indkey + 1
  13726.  
  13727.             -- flush command if necessary
  13728.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  13729.         end -- end of while loop
  13730.         
  13731.         -- add version col as necessary
  13732.         if ((@clause_type in ('upd version','subwins_check')) and (@ts_col is not null))
  13733.         begin
  13734.             --
  13735.             -- @ts_col is version col actually.
  13736.             -- check for special cases for queued processing
  13737.             --
  13738.             exec dbo.sp_MSget_col_position @objid, @columns, @ts_col, @col output
  13739.             if (@clause_type = 'subwins_check')
  13740.                 select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col
  13741.             else
  13742.                 select @cmd = @cmd + @spacer + @ts_col + N' = @' + @col + N'_old'
  13743.  
  13744.             --
  13745.             -- save off command fragment
  13746.             --
  13747.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  13748.         end
  13749.     end -- end of if clause_type
  13750.     -- 'upd rc' is used for column value conflict detection. It is no longer used.
  13751.     else if @clause_type = 'upd rc'
  13752.     begin
  13753.         select @this_col = 1, @art_col = 1
  13754.         while @this_col <= @src_cols
  13755.         begin
  13756.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @colname output, @ccoltype output
  13757.             if @rc = 0
  13758.             begin
  13759.                 select @cmd = @cmd +  @spacer + '(' + @colname + N' = @c' + convert(varchar(4), @this_col) + N'_old or (' 
  13760.                 select @cmd = @cmd + @colname + ' is null and @c' + convert(varchar(4), @this_col) + N'_old is null)) '
  13761.                 select @spacer = N' and 
  13762.     '
  13763.                 exec dbo.sp_MSflush_command @cmd output, 0, @indent
  13764.             end
  13765.             exec dbo.sp_MSflush_command @cmd output, 1, @indent
  13766.             select @this_col = @this_col + 1
  13767.         end
  13768.  
  13769.         -- save off cmd fragment
  13770.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  13771.     end
  13772.     
  13773. END
  13774. go
  13775.  
  13776. raiserror('Creating procedure sp_MSscript_params', 0,1)
  13777. go
  13778. create procedure sp_MSscript_params (
  13779.     @objid   int,
  13780.     @columns binary(32),
  13781.     @postfix nvarchar(8) = NULL,
  13782.     @bOutParams tinyint = 0, -- boolean indicating wether or not to declare timestamp/identity params as output params
  13783.     @outvars nvarchar(4000) = NULL output)
  13784. as
  13785. BEGIN
  13786.     declare @cmd          nvarchar(4000)
  13787.     declare @colname      sysname
  13788.     declare @typestring   nvarchar(4000)
  13789.     declare @spacer       nvarchar(1)
  13790.     declare @spacer2      nvarchar(1)
  13791.     declare @this_col     int
  13792.     declare @art_col      int
  13793.     declare @isset        int
  13794.     declare @pkcolumns    binary(32)
  13795.     declare @ispkcol      int
  13796.  
  13797.     select @spacer = N' '        
  13798.     select @spacer2 = N' '
  13799.     select @art_col = 1
  13800.     select @outvars = null
  13801.     select @cmd = N'    '
  13802.  
  13803.     exec dbo.sp_getarticlepkcolbitmap @objid, @pkcolumns output
  13804.  
  13805.     DECLARE hCColid CURSOR LOCAL FAST_FORWARD FOR 
  13806.     select colid from syscolumns where id = @objid order by colid asc
  13807.  
  13808.     OPEN hCColid
  13809.  
  13810.     FETCH hCColid INTO @this_col
  13811.  
  13812.     WHILE (@@fetch_status <> -1)
  13813.     begin
  13814.  
  13815.         if @columns is not null
  13816.             exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  13817.         else
  13818.             select @isset = 1
  13819.  
  13820.         exec @ispkcol = dbo.sp_isarticlecolbitset @this_col, @pkcolumns
  13821.  
  13822.         if @isset != 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and (iscomputed<>1 or @ispkcol<>0)) 
  13823.         begin
  13824.             exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  13825.             if (@typestring IS NOT NULL)
  13826.             begin
  13827.                 if @postfix is null
  13828.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + N' ' + @typestring 
  13829.                 else
  13830.                     -- old vars
  13831.                     select @cmd = @cmd + @spacer + N'@c' + convert(varchar(4), @this_col) + @postfix + N' ' + @typestring
  13832.  
  13833.                 -- new vars of type timestamp and identity are declared as output params
  13834.                 if @bOutParams = 1 and (@typestring = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1)
  13835.                 begin
  13836.                     select @cmd = @cmd + N' output'
  13837.                     select @outvars = isnull(@outvars, N'') + @spacer2 + N'@c' + convert(varchar(4), @this_col) + N' = ' + @colname 
  13838.                     select @spacer2 = N','
  13839.                 end
  13840.                 
  13841.                 select @spacer = N','
  13842.             end
  13843.             select @art_col = @art_col + 1
  13844.  
  13845.             -- flush command if necessary
  13846.             exec dbo.sp_MSflush_command @cmd output, 1, 4
  13847.        end
  13848.        FETCH hCColid INTO @this_col
  13849.     end
  13850.     CLOSE hCColid
  13851.     DEALLOCATE hCColid
  13852.  
  13853. END
  13854. go
  13855.  
  13856. --
  13857. -- proc to generate the other param declarations and
  13858. -- initial proc declarations and assignments for
  13859. -- synctran/queued updating procs
  13860. --
  13861. raiserror('Creating procedure sp_MSscript_procbodystart', 0,1)
  13862. go
  13863. create procedure sp_MSscript_procbodystart (
  13864.     @queued_pub        bit = 0
  13865. )
  13866. as
  13867. BEGIN
  13868.     declare @cmd          nvarchar(4000)
  13869.  
  13870.     --
  13871.     -- script the initial declarations and assignments
  13872.     --
  13873.     select @cmd = N'    ,@execution_mode tinyint = 0)
  13874. AS
  13875. BEGIN
  13876.     set nocount on
  13877.     declare    @retcode int
  13878.         , @rowcount int
  13879.         , @error int
  13880.         , @reinit int
  13881.         , @cmd nvarchar(4000)'
  13882.     exec dbo.sp_MSflush_command @cmd output, 1
  13883.  
  13884.     select @cmd = N'
  13885.     declare    @immediate tinyint '
  13886.     if (@queued_pub = 1)
  13887.     begin
  13888.         select @cmd = @cmd + N' 
  13889.         , @QFirstPass tinyint
  13890.         , @QPubWins tinyint
  13891.         , @QSubWins tinyint
  13892.         , @QReinit tinyint
  13893.         , @cftcase int
  13894. '
  13895.     end
  13896.     exec dbo.sp_MSflush_command @cmd output, 1
  13897.  
  13898.     select @cmd = N' 
  13899.     select     @immediate = 0 '
  13900.     if (@queued_pub = 1)
  13901.     begin
  13902.         select @cmd = @cmd + N'     
  13903.         , @QFirstPass = 1
  13904.         , @QPubWins  = 2
  13905.         , @QSubWins = 3
  13906.         , @QReinit = 4
  13907. '
  13908.     end    
  13909.     exec dbo.sp_MSflush_command @cmd output, 1
  13910.  
  13911.     return 0
  13912. END
  13913. go
  13914. EXEC dbo.sp_MS_marksystemobject sp_MSscript_procbodystart
  13915. GO
  13916.  
  13917.  
  13918. raiserror('Creating procedure sp_MSscript_begintrig1', 0,1)
  13919. go
  13920. create procedure sp_MSscript_begintrig1 (
  13921.     @trigname      sysname
  13922.     ,@objid         int
  13923.     ,@procname      sysname
  13924.     ,@filter_clause nvarchar(4000)
  13925.     ,@op_type       char(3) = 'ins' -- ins, upd, del
  13926.     ,@fisqueued      bit = 0 -- 1 = Queued subscription
  13927. )
  13928. as
  13929. BEGIN
  13930.     declare @cmd       nvarchar(4000)
  13931.             ,@start     int
  13932.             ,@sub_len   int
  13933.             ,@qualname  nvarchar(512)
  13934.  
  13935.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  13936.  
  13937.     -- construct trigger name
  13938.     select @cmd = N'create trigger ' + QUOTENAME(@trigname) + N' on ' + @qualname + N' for '
  13939.     select @cmd = case
  13940.                     when (@op_type = 'ins') then @cmd + N'insert '
  13941.                     when (@op_type = 'upd') then @cmd + N'update '
  13942.                     when (@op_type = 'del') then @cmd + N'delete '
  13943.                 end
  13944.     select @cmd = @cmd + N'not for replication
  13945. as
  13946. '
  13947.     insert into #proctext(procedure_text) values (@cmd)
  13948.  
  13949.     --
  13950.     -- declare common local variables
  13951.     --
  13952.     --        ,@update_mode char(40)
  13953.     --        ,@failover_mode char(10)
  13954.     --
  13955.     insert into #proctext(procedure_text) values (N'
  13956.     declare     @rc int
  13957.         ,@retcode int
  13958.         ,@connect_string nvarchar(2000)
  13959.         ,@rpc_proc nvarchar(4000)
  13960.         ,@rpc_types nvarchar(4000)
  13961.         ,@update_mode_id int
  13962.         ,@bitmap varbinary(4000)
  13963.         ,@version_guid uniqueidentifier
  13964.         ,@trigger_op char(10) ')
  13965.  
  13966.         --
  13967.         -- queued specific declarations
  13968.         --
  13969.     insert into #proctext(procedure_text) values (N'
  13970.         ,@failover_mode_id int
  13971.         ,@queue_server sysname
  13972.         ,@queue_id sysname
  13973.         ,@tran_id varchar(255)
  13974.         ,@subscriber sysname
  13975.         ,@subscriber_db sysname 
  13976.         ,@partial_cmd bit
  13977.         ,@start_offset int
  13978.         ,@end_offset int
  13979.         ,@vb_buffer varbinary(8000)
  13980.         ,@vb_bufferlen int        
  13981.         ')
  13982.  
  13983.     -- script variables used to retrieve data from inserted table
  13984.     if @op_type in ('ins', 'upd')
  13985.     begin
  13986.         insert into #proctext(procedure_text) values(N'
  13987.     declare ')
  13988.             exec dbo.sp_MSscript_params @objid, null, null, 0, null
  13989.     end
  13990.     insert into #proctext(procedure_text) values(N'
  13991.     declare ')
  13992.     exec dbo.sp_MSscript_params @objid, null, '_old',  0, null
  13993.  
  13994.     -- Set @rc, @subscriber and @subscriber_db
  13995.     -- Optimization. Return immediately if no row changed
  13996.     select @cmd = N'
  13997.  
  13998.     select @rc = @@ROWCOUNT, @subscriber = @@SERVERNAME, @subscriber_db = db_name() 
  13999.     if @rc = 0 
  14000.         return 
  14001.     set nocount on '
  14002.     insert into #proctext(procedure_text) values(@cmd)
  14003.         
  14004.     -- set column update bitmap for update trigger
  14005.     if @op_type in ('upd')
  14006.     begin
  14007.         declare     @num_bytes        int
  14008.                 ,@i_byte            int
  14009.                 ,@i_bit            tinyint
  14010.                 ,@len_before nvarchar(10)
  14011.                 ,@len_after nvarchar(10)
  14012.                 ,@index1 nvarchar(10)
  14013.                 ,@index2 nvarchar(10)
  14014.                 ,@this_col         int
  14015.                 ,@max_col            int
  14016.                 ,@total_col        int
  14017.  
  14018.         --
  14019.         -- check if the subscriber table was altered for column changes
  14020.         --
  14021.         select @max_col = max(colid)
  14022.                 ,@total_col = count(colid)
  14023.             from syscolumns where id = @objid
  14024.         if (@total_col = @max_col)
  14025.         begin
  14026.             --
  14027.             -- actual colid and relative column order are same
  14028.             --
  14029.             insert into #proctext(procedure_text) values(N'
  14030.     select @bitmap = columns_updated() 
  14031.     ')
  14032.         end
  14033.         else
  14034.         begin
  14035.             --
  14036.             -- we need to convert the columns_updated bitmap to 
  14037.             -- a bitmap that contains relative column information
  14038.             --
  14039.             select @cmd = N'
  14040.     select @bitmap = fn_repladjustcolumnmap( ' + cast(@objid as sysname) + N', ' +
  14041.                 cast(@total_col as sysname) + N', columns_updated())'
  14042.             insert into #proctext(procedure_text) values(@cmd)
  14043.             select @cmd = N'                
  14044.     if (@bitmap is null) 
  14045.     begin
  14046.         raiserror(''fn_repladjustcolumnmap could not create column mapping'', 16, 1)
  14047.         goto FAILURE
  14048.     end
  14049.     '
  14050.             insert into #proctext(procedure_text) values(@cmd)
  14051.         end
  14052.  
  14053.             --
  14054.             -- Mark the version bit in the bitmap as updated.
  14055.             --
  14056.             select @cmd = N'
  14057.     ' + '-- set the bit for msrepl_tran_version'
  14058.         insert into #proctext(procedure_text) values(@cmd)
  14059.  
  14060.         -- get actual column id
  14061.         exec dbo.sp_MSget_col_position @objid, null, 'msrepl_tran_version', @this_col = @this_col output
  14062.         if (@total_col < @max_col)
  14063.         begin
  14064.             --
  14065.             -- this table has altered columns, create a mapping between
  14066.             -- relative column position and actual column id
  14067.             --
  14068.             declare @colmap table (relativeorder int identity(1,1), colid int)
  14069.             insert into @colmap (colid)
  14070.                 select colid from syscolumns where id = @objid order by colid
  14071.             if (@@error != 0)
  14072.             begin
  14073.                 raiserror('Could not create column mapping', 16, -1)
  14074.                 return (1)
  14075.             end
  14076.  
  14077.             --
  14078.             -- get the relative column position for msrepl_tran_version
  14079.             --
  14080.             select @this_col = relativeorder from @colmap where colid = @this_col 
  14081.         end
  14082.     
  14083.         select @num_bytes = @total_col / 8 + 1
  14084.             ,@i_byte = 1 + (@this_col-1) / 8
  14085.             ,@i_bit  = power(2, (@this_col-1) % 8 )
  14086.  
  14087.         select @len_before = convert(nvarchar(10), @i_byte -1)
  14088.             ,@index1 = convert(nvarchar(10), @i_byte)
  14089.             ,@index2 = convert(nvarchar(10), @i_byte + 1)
  14090.             ,@len_after = convert(nvarchar(10), @num_bytes - @i_byte)
  14091.  
  14092.         select @cmd = N'
  14093.     select @bitmap = substring(@bitmap, 1, ' + @len_before + 
  14094.             ') + (convert(binary(1), substring(@bitmap, ' + @index1 + 
  14095.             ', 1) | convert(tinyint,' + convert(nvarchar(10), @i_bit) + 
  14096.             '))) + substring(@bitmap, ' + @index2 + 
  14097.             ', ' + @len_after + 
  14098.             ') '
  14099.         exec dbo.sp_MSflush_command @cmd, 1
  14100.     end
  14101.  
  14102.     select @cmd = N'
  14103.     select @version_guid = newid() '
  14104.     insert into #proctext(procedure_text) values(@cmd) 
  14105.  
  14106.     -- Partition check statement
  14107.     if @filter_clause IS NOT NULL
  14108.     begin
  14109.         declare @retcode int
  14110.         exec @retcode = sp_MSsubst_filter_names NULL, N'inserted', @filter_clause output
  14111.         if @retcode <> 0 or @@error <> 0
  14112.             return 1        
  14113.                 
  14114.         select @cmd = N'
  14115.     if exists (select * from inserted where not ('
  14116.         insert into #proctext(procedure_text) values(@cmd) 
  14117.             
  14118.         -- break filter_clause into chunks of 255
  14119.         select @start = 1
  14120.         while @start < len(@filter_clause)
  14121.         begin
  14122.             if len(@filter_clause) < 255
  14123.                 select @sub_len = len(@filter_clause)
  14124.             else
  14125.                 select @sub_len = 255
  14126.             select @cmd = substring(@filter_clause, @start, @sub_len)
  14127.             exec dbo.sp_MSflush_command @cmd output, 1
  14128.             select @start = @start + @sub_len
  14129.         end
  14130.                 
  14131.         select @cmd = N'))
  14132.      begin 
  14133.          exec sp_MSreplraiserror 21034
  14134.          goto FAILURE 
  14135.      end '
  14136.         insert into #proctext(procedure_text) values(@cmd) 
  14137.     end
  14138.  
  14139.     -- trigger nesting checks
  14140.     if @op_type in ('upd')
  14141.     begin
  14142.         select @cmd = N'
  14143.     ' + '-- trigger nesting check
  14144.     exec @retcode = dbo.sp_check_sync_trigger @@procid, @trigger_op OUTPUT 
  14145.     if (@retcode = 1)
  14146.         return '
  14147.         insert into #proctext(procedure_text) values(@cmd) 
  14148.     end
  14149.  
  14150. END
  14151. go
  14152.  
  14153. raiserror('Creating procedure sp_MSscript_begintrig2', 0,1)
  14154. go
  14155. create procedure sp_MSscript_begintrig2 (
  14156.     @publisher   sysname
  14157.     ,@publisher_db sysname
  14158.     ,@publication sysname
  14159.     ,@objid       int
  14160.     ,@op_type     char(3) = 'ins' -- ins, upd, del
  14161.     ,@agent_id    int
  14162.     ,@fisqueued      bit = 0 -- 1 = Queued subscription
  14163. )
  14164. as
  14165. BEGIN
  14166.     declare @cmd nvarchar(4000)
  14167.             ,@queue_server sysname
  14168.  
  14169.     if @op_type = 'ins' 
  14170.     begin
  14171.         insert into #proctext(procedure_text) values(N'
  14172.     if Objectproperty(@@procid,''TriggerInsertOrder'') != 1    
  14173.     begin
  14174.         declare @trigname sysname
  14175.         select @trigname = object_name(@@procid)
  14176.  
  14177.         raiserror (21128, 16, 1, @trigname)
  14178.         goto FAILURE
  14179.     end ')
  14180.     end
  14181.     else if @op_type = 'upd' 
  14182.     begin
  14183.         insert into #proctext(procedure_text) values(N'
  14184.     if Objectproperty(@@procid,''TriggerUpdateOrder'') != 1    
  14185.     begin
  14186.         declare @trigname sysname
  14187.         select @trigname = object_name(@@procid)
  14188.  
  14189.         raiserror (21129, 16, 1, @trigname)
  14190.         goto FAILURE
  14191.     end ')
  14192.     end
  14193.     else if @op_type = 'del' 
  14194.     begin
  14195.         insert into #proctext(procedure_text) values(N'
  14196.     if Objectproperty(@@procid,''TriggerDeleteOrder'') != 1
  14197.     begin
  14198.         declare @trigname sysname
  14199.         select @trigname = object_name(@@procid)
  14200.  
  14201.         raiserror (21130, 16, 1, @trigname)
  14202.         goto FAILURE
  14203.     end ')
  14204.     end
  14205.  
  14206.     --
  14207.     -- scripting for debug messages
  14208.     --
  14209.     select @cmd = N'
  14210.     select @update_mode_id = update_mode 
  14211.     from dbo.MSsubscription_agents where id = ' + convert(nvarchar(10), @agent_id) + N' '
  14212.     insert into #proctext(procedure_text) values (@cmd)
  14213.  
  14214.     --
  14215.     -- continue with scripting
  14216.     --
  14217.     select @cmd = N'
  14218.     ' + N'--
  14219.     ' + N'-- initialize and validate based on update mode
  14220.     ' + N'--
  14221.     if @update_mode_id = 1
  14222.     begin
  14223.         exec @retcode = dbo.sp_MSget_publisher_rpc @@procid, @connect_string output
  14224.         if @retcode <>0 or @@error <> 0 goto FAILURE
  14225.     end'
  14226.     insert into #proctext(procedure_text) values (@cmd)
  14227.  
  14228.     --
  14229.     -- continue with scripting
  14230.     --
  14231.     if (@fisqueued = 1)
  14232.     begin
  14233.         --
  14234.         -- Queued specific scripting
  14235.         --
  14236.         select @cmd = N'
  14237.     else if @update_mode_id in (2,4)
  14238.     begin
  14239.         select @queue_server = queue_server, @queue_id = queue_id from dbo.MSsubscription_agents where id = ' + convert(nvarchar(10), @agent_id) + N'
  14240.         if (@queue_id is NULL) 
  14241.             goto FAILURE
  14242.     end'
  14243.         insert into #proctext(procedure_text) values (@cmd)
  14244.  
  14245.         --
  14246.         -- continue with scripting
  14247.         --
  14248.         select @cmd = N'
  14249.     else if @update_mode_id in (3,5)
  14250.     begin
  14251.         select @queue_server = queue_server, @queue_id = queue_id from dbo.MSsubscription_agents 
  14252.             where id = ' + convert(nvarchar(10), @agent_id) + N' and failover_mode = 1 '
  14253.         insert into #proctext(procedure_text) values (@cmd)
  14254.  
  14255.         --
  14256.         -- continue with scripting
  14257.         --
  14258.         select @cmd = N'
  14259.         if (@queue_id is NULL)
  14260.         begin
  14261.             exec @retcode = dbo.sp_MSget_publisher_rpc @@procid, @connect_string output
  14262.             if @retcode <>0 or @@error <> 0 
  14263.                 goto FAILURE
  14264.         end
  14265.     end'
  14266.         insert into #proctext(procedure_text) values (@cmd)
  14267.     end
  14268.     
  14269.     --
  14270.     -- continue with scripting
  14271.     --
  14272.     select @cmd = N'
  14273.     else if @update_mode_id = 0
  14274.     begin
  14275.         raiserror (''read only mode - no updates allowed'', 16, 1)
  14276.         goto FAILURE
  14277.     end
  14278.     else
  14279.     begin
  14280.         raiserror(''invalid update mode %d'', 16, 1, @update_mode_id)
  14281.         goto FAILURE
  14282.     end '
  14283.     insert into #proctext(procedure_text) values (@cmd)
  14284.  
  14285.     if (@fisqueued = 1)
  14286.     begin        
  14287.         select @cmd = N'
  14288.     ' + N'--
  14289.     ' + N'-- set queue prefix for MSMQ cases
  14290.     ' + N'--
  14291.     if (@update_mode_id in (2,3))
  14292.     begin
  14293.         select @queue_id = N''DIRECT=OS:'' + @queue_server + N''\PRIVATE$\'' + @queue_id 
  14294.     end'
  14295.         insert into #proctext(procedure_text) values (@cmd)
  14296.  
  14297.         --
  14298.         -- Get failover mode scripting
  14299.         --
  14300.         select @cmd = N'
  14301.     ' + N'--
  14302.     ' + N'-- get failover mode
  14303.     ' + N'--
  14304.     if @update_mode_id in (3,5)
  14305.     begin
  14306.         select @failover_mode_id = failover_mode
  14307.         from dbo.MSsubscription_agents where id = '
  14308.         + convert(nvarchar(10), @agent_id) + ' and update_mode in (3,5)
  14309.     end'
  14310.         insert into #proctext(procedure_text) values (@cmd)
  14311.     end
  14312.     
  14313.     --
  14314.     -- Start the distributed tran and get the transaction id as we may use
  14315.     -- it for queue sends
  14316.     --
  14317.     select @cmd = N'
  14318.     ' + N'--
  14319.     ' + N'-- begin tran or dist tran based on update mode
  14320.     ' + N'--
  14321.     if (@update_mode_id in (4,5))
  14322.         BEGIN TRAN
  14323.     else
  14324.         BEGIN DISTRIBUTED TRAN
  14325.     '
  14326.     insert into #proctext(procedure_text) values (@cmd)
  14327.         
  14328.     if (@fisqueued = 1)
  14329.     begin
  14330.         select @cmd = N'
  14331.     ' + N'--
  14332.     ' + N'-- save the transaction token for later use
  14333.     ' + N'--
  14334.     exec sp_getbindtoken @out_token = @tran_id OUTPUT , @for_xp_flag = 1 '
  14335.         insert into #proctext(procedure_text) values (@cmd)
  14336.     end
  14337.  
  14338.     --
  14339.     -- all done with scripting
  14340.     --
  14341.     return 0
  14342. END
  14343. go
  14344.  
  14345. raiserror('Creating procedure sp_MSscript_endtrig', 0,1)
  14346. go
  14347. create proc sp_MSscript_endtrig
  14348. as
  14349. BEGIN
  14350.     declare @cmd nvarchar(4000)
  14351.  
  14352.     select @cmd = N'
  14353.     if (@@trancount > 0)
  14354.         commit tran
  14355.     return 
  14356.  
  14357. FAILURE:
  14358.     if (@@trancount > 0)
  14359.     begin
  14360.         exec sp_MSreplraiserror 20512
  14361.         rollback tran
  14362.     end '
  14363.     insert into #proctext(procedure_text) values(@cmd)
  14364. END
  14365. go
  14366.  
  14367. raiserror('Creating procedure sp_MSscript_trigger_variables', 0,1)
  14368. go
  14369.  
  14370. create procedure sp_MSscript_trigger_variables
  14371. (
  14372.     @objid int,
  14373.     @prefix char(1) = null, -- null or '@'
  14374.     @postfix varchar(4) = null,
  14375.     @indent int = 0,
  14376.     @spacer nvarchar(1) = N' ', 
  14377.     @bOutput_params tinyint = 0,  -- declare output params if necessary
  14378.     @identity_col sysname = null,
  14379.     @ts_col sysname = null,
  14380.     @include_type bit = 0,
  14381.     @set_nulls    bit = 0,
  14382.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  14383.     @is_new        bit = 0,
  14384.     @primary_key_bitmap varbinary(4000) = NULL,
  14385.     @no_output bit = 0
  14386. )
  14387. as
  14388. begin
  14389.     declare @cmd          nvarchar(4000)
  14390.             ,@colname      sysname
  14391.             ,@ccoltype     sysname
  14392.             ,@src_cols     int
  14393.             ,@this_col     int
  14394.             ,@total_col        int
  14395.             ,@indkey            int
  14396.             ,@fcreatedcolmap    bit
  14397.             ,@rc           int
  14398.             ,@column          nvarchar(4000)
  14399.     declare @colmap table (relativeorder int identity(1,1), colid int)
  14400.  
  14401.     -- script cursor select variables
  14402.     select @cmd = N''
  14403.             ,@indkey = 1
  14404.             ,@fcreatedcolmap = 0
  14405.     select @src_cols = max(colid)
  14406.             ,@total_col = count(colid)
  14407.         from syscolumns where id = @objid
  14408.     exec dbo.sp_MSpad_command @cmd output, @indent
  14409.  
  14410.     --
  14411.     -- check if column Id match relative column order
  14412.     -- for trigger scripting
  14413.     --
  14414.     if (@total_col < @src_cols)
  14415.     begin
  14416.         --
  14417.         -- this table may have altered columns, so when we need to 
  14418.         -- set a mapping for using the bitmaps properly as the bitmap
  14419.         -- always refers relative column order
  14420.         --
  14421.         insert into @colmap (colid)
  14422.             select colid from syscolumns where id = @objid order by colid
  14423.         if (@@error != 0)
  14424.         begin
  14425.             raiserror('Could not create column mapping', 16, -1)
  14426.             return (1)
  14427.         end
  14428.         select @fcreatedcolmap = 1
  14429.     end
  14430.  
  14431.     while (@indkey <= @total_col)
  14432.     begin
  14433.         --
  14434.         -- set the actual column id for this relative order in the bitmap if necessary
  14435.         --
  14436.         if (@fcreatedcolmap = 1)
  14437.         begin
  14438.             select @this_col = colid from @colmap 
  14439.                 where relativeorder = @indkey 
  14440.         end
  14441.         else
  14442.         begin
  14443.             select @this_col = @indkey
  14444.         end
  14445.  
  14446.         --
  14447.         -- Get column name
  14448.         -- Don't include timestamp or computed columns        
  14449.         --
  14450.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  14451.         if @rc = 0 and EXISTS (select name from syscolumns where id=@objid and colid=@this_col and iscomputed<>1 and xtype <> 189)
  14452.         begin
  14453.             if @prefix is null
  14454.             begin
  14455.             
  14456.                 if (@set_nulls = 1)
  14457.                 begin
  14458.                     -- Optimization:
  14459.                     -- Get null or actual column name
  14460.                     -- Note: the output is quoted.
  14461.                     exec dbo.sp_MSget_synctran_column 
  14462.                         @ts_col = @ts_col,
  14463.                         @op_type = @op_type, -- 'ins, 'upd', 'del'
  14464.                         @is_new = @is_new,
  14465.                         @primary_key_bitmap = @primary_key_bitmap,
  14466.                         @colname = @colname,
  14467.                         @this_col = @this_col,
  14468.                         @column = @column output,
  14469.                         @from_proc = 0, 
  14470.                         @coltype = @ccoltype, 
  14471.                         @type = NULL,
  14472.                         @art_col = @indkey
  14473.                     select @cmd = @cmd + @spacer + @column + isnull(@postfix, N'')
  14474.                 end
  14475.                 else
  14476.                 begin
  14477.                     -- set null is false
  14478.                     select @cmd = @cmd + @spacer + N'[' + @colname + isnull(@postfix, N'') + N']'
  14479.                 end
  14480.             end
  14481.             else
  14482.             begin
  14483.                 -- prefix was specified
  14484.                 select @cmd = @cmd + @spacer + isnull(@prefix, N'') 
  14485.                     + N'c' + RTRIM(convert(nvarchar(4), @this_col)) + isnull(@postfix, N'')
  14486.             end
  14487.  
  14488.             if (@include_type = 1)
  14489.             begin
  14490.                 declare @typestring nvarchar(100)
  14491.                 exec dbo.sp_MSget_type @objid, @this_col, @colname output, @typestring OUTPUT
  14492.                 select @cmd = @cmd +  N' ' + @typestring 
  14493.             end
  14494.  
  14495.             -- new vars of type timestamp and identity are declared as output params
  14496.             if (@bOutput_params = 1 and (@ccoltype = N'timestamp' or ColumnProperty(@objid, @colname, 'IsIdentity') = 1))
  14497.                 or (@colname = @identity_col or @colname = @ts_col)
  14498.             begin
  14499.                 -- YWU: Do this to avoid output in cursor declaration statement.
  14500.                 -- The right thing seems to be set output only when bOutput_params is set
  14501.                 -- but it seems not the way this sp is called.
  14502.                 if @set_nulls = 0 and @no_output = 0
  14503.                     select @cmd = @cmd + N' output'
  14504.             end
  14505.  
  14506.             select @spacer = N','
  14507.         end -- if rc=0 and exists ...
  14508.         
  14509.         exec dbo.sp_MSflush_command @cmd output, 0, @indent
  14510.         select @indkey = @indkey + 1
  14511.     end -- while () loop
  14512.  
  14513.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14514.     insert into #proctext(procedure_text) values(N'
  14515. ') 
  14516.  
  14517. end
  14518. go
  14519.  
  14520. raiserror('Creating procedure sp_MSscript_trigger_assignment', 0,1)
  14521. go
  14522.  
  14523. create procedure sp_MSscript_trigger_assignment (
  14524.     @objid int
  14525.     ,@postfix char(4) = null
  14526.     ,@indent int = 0
  14527.     ,@ts_col sysname
  14528.     ,@op_type char(3) -- 'ins, 'upd', 'del'
  14529.     ,@is_new    bit
  14530.     ,@primary_key_bitmap varbinary(4000) = null
  14531. )
  14532. as
  14533. BEGIN
  14534.     declare @cmd          nvarchar(4000)
  14535.             ,@colname      sysname
  14536.             ,@spacer       nvarchar(1)
  14537.             ,@ccoltype     sysname
  14538.             ,@src_cols     int
  14539.             ,@this_col     int
  14540.             ,@total_col        int
  14541.             ,@indkey            int
  14542.             ,@fcreatedcolmap    bit
  14543.             ,@rc           int
  14544.             ,@column          nvarchar(4000)
  14545.     declare @colmap table (relativeorder int identity(1,1), colid int)
  14546.  
  14547.     -- initialize
  14548.     select @spacer = N' '
  14549.             ,@indkey = 1
  14550.             ,@fcreatedcolmap = 0
  14551.     select @src_cols = max(colid)
  14552.             ,@total_col = count(colid)
  14553.         from syscolumns where id = @objid
  14554.     exec dbo.sp_MSpad_command @cmd output, @indent
  14555.  
  14556.     --
  14557.     -- check if column Id match relative column order
  14558.     -- for trigger scripting
  14559.     --
  14560.     if (@total_col < @src_cols)
  14561.     begin
  14562.         --
  14563.         -- this table may have altered columns, so when we need to 
  14564.         -- set a mapping for using the bitmaps properly as the bitmap
  14565.         -- always refers relative column order
  14566.         --
  14567.         insert into @colmap (colid)
  14568.             select colid from syscolumns where id = @objid order by colid
  14569.         if (@@error != 0)
  14570.         begin
  14571.             raiserror('Could not create column mapping', 16, -1)
  14572.             return (1)
  14573.         end
  14574.         select @fcreatedcolmap = 1
  14575.     end
  14576.  
  14577.     while (@indkey <= @total_col)
  14578.     begin
  14579.         --
  14580.         -- set the actual column id for this relative order in the bitmap if necessary
  14581.         --
  14582.         if (@fcreatedcolmap = 1)
  14583.         begin
  14584.             select @this_col = colid from @colmap 
  14585.                 where relativeorder = @indkey 
  14586.         end
  14587.         else
  14588.         begin
  14589.             select @this_col = @indkey
  14590.         end
  14591.  
  14592.         --
  14593.         -- Get column name
  14594.         --
  14595.         exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 0, @colname output, @ccoltype output
  14596.         if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  14597.         begin
  14598.             -- Optimization:
  14599.             -- Get null or actual column name
  14600.             -- Note: the output is quoted.
  14601.             exec dbo.sp_MSget_synctran_column 
  14602.                 @ts_col = @ts_col,
  14603.                 @op_type = @op_type, -- 'ins, 'upd', 'del'
  14604.                 @is_new = @is_new,
  14605.                 @primary_key_bitmap = @primary_key_bitmap,
  14606.                 @colname = @colname,
  14607.                 @this_col = @this_col,
  14608.                 @column = @column output,
  14609.                 @from_proc = 0, 
  14610.                 @coltype = NULL, 
  14611.                 @type = NULL,
  14612.                 @art_col = @indkey
  14613.  
  14614.             select @cmd = @cmd + @spacer + N'@c' + 
  14615.                 convert(sysname, @this_col) + isnull(@postfix, N'') + 
  14616.                 N' = ' + @column  
  14617.                 
  14618.             select @spacer = N','
  14619.         end
  14620.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14621.         select @indkey = @indkey + 1
  14622.     end
  14623.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14624.  
  14625. END
  14626. go
  14627.  
  14628. raiserror('Creating procedure sp_MSscript_trigger_fetch_statement', 0,1)
  14629. go
  14630.  
  14631. create procedure sp_MSscript_trigger_fetch_statement (
  14632.     @objid   int, 
  14633.     @op_type char(3) = 'ins',
  14634.     @indent   int = 0
  14635. )
  14636. as
  14637. BEGIN
  14638.     declare @cmd          nvarchar(4000)
  14639.  
  14640.     -- script fetch statements
  14641.     if @op_type in ('ins', 'upd')
  14642.     begin
  14643.         exec dbo.sp_MSpad_command @cmd output, @indent
  14644.         select @cmd = @cmd + N'fetch next from rpl_ins_cursor into 
  14645. '
  14646.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14647.         exec dbo.sp_MSscript_trigger_variables @objid, '@', null, @indent, ' '
  14648.     end
  14649.  
  14650.     if @op_type in ('ins')
  14651.     begin
  14652.         exec dbo.sp_MSpad_command @cmd output, @indent
  14653.         select @cmd = @cmd + N'fetch next from rpl_ins2_cursor into 
  14654. '
  14655.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14656.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  14657.     end
  14658.  
  14659.     if @op_type in ('upd', 'del')
  14660.     begin
  14661.         exec dbo.sp_MSpad_command @cmd output, @indent
  14662.         select @cmd = @cmd + N'fetch next from rpl_del_cursor into 
  14663. '
  14664.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  14665.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' '
  14666.     end
  14667. END
  14668. go
  14669.  
  14670. raiserror('Creating procedure sp_MSscript_trigger_exec_rpc ', 0,1)
  14671. go
  14672. create procedure sp_MSscript_trigger_exec_rpc (
  14673.     @publisher   sysname,
  14674.     @publisherdb sysname,
  14675.     @publication sysname,
  14676.     @procname   sysname,
  14677.     @proc_owner sysname,
  14678.     @cftproc    sysname,
  14679.     @objid       int, 
  14680.     @op_type     char(3) = 'ins', 
  14681.     @indent      int = 0,
  14682.     @identity_col sysname = null,
  14683.     @ts_col       sysname = null,
  14684.     @primary_key_bitmap   varbinary(4000)
  14685. )
  14686. as
  14687. BEGIN
  14688.     declare @cmd nvarchar(4000)
  14689.             ,@min_identity int
  14690.             ,@max_identity int
  14691.             ,@fisqueued bit
  14692.             ,@varindent int
  14693.             ,@object_owner sysname
  14694.  
  14695.     select @fisqueued = case when (@cftproc is NULL) then 0 else 1 end
  14696.  
  14697.     --
  14698.     -- Set version guid param and column first.
  14699.     --
  14700.     if @op_type in ('upd')
  14701.     begin
  14702.         exec dbo.sp_MSscript_trigger_version_updates @objid, 'msrepl_tran_version', @indent,
  14703.             @primary_key_bitmap
  14704.     end
  14705.  
  14706.     --
  14707.     -- continue scripting
  14708.     --
  14709.     select @cmd = N'
  14710.         if (@update_mode_id = 1) or (@update_mode_id in (3, 5) and @failover_mode_id = 0)
  14711.         begin 
  14712.             ' + N'-- 
  14713.             ' + N'-- immediate mode - check if publisher is local
  14714.             ' + N'-- 
  14715.             if @connect_string is null 
  14716.             begin '
  14717.     insert into #proctext(procedure_text) values (@cmd)
  14718.  
  14719.     --
  14720.     -- prepare the proc invocation
  14721.     -- 1st two variables are subscriber server name and database name for cycle detection
  14722.     --
  14723.     select @cmd = N'
  14724.                 select @rpc_proc = N''' + quotename(@publisher) collate database_default + N'.' + 
  14725.                     quotename(master.dbo.fn_MSgensqescstr(@publisherdb)) collate database_default + N'.' + 
  14726.                     quotename(master.dbo.fn_MSgensqescstr(@proc_owner)) collate database_default + N'.' + 
  14727.                     quotename(master.dbo.fn_MSgensqescstr(@procname)) collate database_default + N''' 
  14728.                 exec @retcode = @rpc_proc @subscriber, @subscriber_db,
  14729.             '
  14730.     insert into #proctext(procedure_text) values (@cmd)
  14731.  
  14732.     --
  14733.     -- script the trigger variables
  14734.     --
  14735.     select @min_identity = @@identity
  14736.     if @op_type in ('ins', 'upd')
  14737.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @indent, N'', 0,  @identity_col, @ts_col
  14738.  
  14739.     if @op_type = 'upd'
  14740.     begin
  14741.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ',', 0, null, null
  14742.         insert into #proctext(procedure_text) values (N'
  14743.                         ,@bitmap')
  14744.     end
  14745.  
  14746.     else if @op_type = 'del'
  14747.         exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @indent, ' ', 0, null, null
  14748.  
  14749.     select @max_identity = @@identity
  14750.     
  14751.     --
  14752.     -- continue scripting
  14753.     --
  14754.     select @cmd = N'
  14755.                 if (@@error != 0 or @retcode != 0)
  14756.                 begin 
  14757.                     if (@retcode = -2)
  14758.                         exec sp_MSreplraiserror 21064
  14759.                     else if @retcode = 5
  14760.                         exec sp_MSreplraiserror 20515
  14761.                     else
  14762.                         exec sp_MSreplraiserror 21054
  14763.                     goto FAILURE 
  14764.                 end
  14765.             end
  14766.             else
  14767.             begin'
  14768.     insert into #proctext(procedure_text) values (@cmd)
  14769.     
  14770.     --
  14771.     -- prepare the RPC invocation
  14772.     --
  14773.     select @cmd = N'
  14774.                 select @rpc_proc = N''
  14775.                 declare @retcode int 
  14776.                 exec @retcode = '' + N'
  14777.     select @cmd = @cmd + quotename('OpenDataSource(''SQLOLEDB'',N' ,'''') 
  14778.     select @cmd = @cmd + '+ '''''''' + replace(@connect_string, '''''''', '''''''''''''''') + N'''''''' + '
  14779.     select @cmd = @cmd + 'N'').'' + N''' 
  14780.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@publisherdb)) collate database_default + '.'
  14781.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@proc_owner)) collate database_default + '.'
  14782.     select @cmd = @cmd + quotename(master.dbo.fn_MSgensqescstr(@procname)) collate database_default + ''' + quotename(@subscriber) collate database_default + '','' + quotename(@subscriber_db) collate database_default + '', '' + 
  14783.                 '''
  14784.     insert into #proctext(procedure_text) values (@cmd)
  14785.  
  14786.     --
  14787.     -- script the trigger variables
  14788.     --
  14789.     select @varindent = @indent + 4
  14790.     if @op_type in ('ins', 'upd')
  14791.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', 0, N'', 0,  @identity_col, @ts_col
  14792.  
  14793.     if @op_type = 'upd'
  14794.     begin
  14795.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @varindent, ',', 0, null, null
  14796.         insert into #proctext(procedure_text) values (N'
  14797.                         ,@bitmap')
  14798.     end
  14799.     else if @op_type = 'del'
  14800.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', 0, ' ', 0, null, null
  14801.  
  14802.     --
  14803.     -- Must raise error right before exiting the dynamic exec so that it will be picked up.
  14804.     --
  14805.     select @cmd = N'
  14806.         '' + '' if (@@error != 0 or @retcode != 0) 
  14807.         begin 
  14808.             if (@retcode = -2) 
  14809.                 exec sp_MSreplraiserror 21064 
  14810.             else if @retcode = 5 
  14811.                 exec sp_MSreplraiserror 20515
  14812.             else 
  14813.                 exec sp_MSreplraiserror 21054 
  14814.         end''
  14815.         '
  14816.     insert into #proctext(procedure_text) values (@cmd)
  14817.  
  14818.     --
  14819.     -- Get parameter datatypes
  14820.     --
  14821.     insert into #proctext(procedure_text) values (N'
  14822.                 select @rpc_types = ''')
  14823.     if @op_type in ('ins', 'upd')
  14824.         exec dbo.sp_MSscript_trigger_variables @objid, '@', N'' , 0, N'', 0,  @identity_col, @ts_col, 1
  14825.     if @op_type = 'upd'
  14826.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', @varindent, ',', 0, null, null, 1
  14827.     else if @op_type = 'del'
  14828.         exec dbo.sp_MSscript_trigger_variables @objid, '@', 'o', 0, ' ', 0, null, null, 1
  14829.     
  14830.     exec dbo.sp_MSpad_command @cmd output, @indent
  14831.     select @cmd = @cmd + N''''
  14832.     insert into #proctext(procedure_text) values (@cmd)
  14833.  
  14834.     if @op_type = 'upd'
  14835.     begin
  14836.         insert into #proctext(procedure_text) values (N'
  14837.                 select @rpc_types = @rpc_types + '', @bitmap varbinary(4000)'' ')
  14838.     end
  14839.  
  14840.     --
  14841.     -- make rpc call
  14842.     --
  14843.     insert into #proctext(procedure_text) values (N'
  14844.                 exec @retcode = dbo.sp_executesql @rpc_proc, @rpc_types, 
  14845. ')
  14846.  
  14847.     --
  14848.     -- Get parameters again
  14849.     --
  14850.     insert into #proctext(procedure_text) select procedure_text from #proctext
  14851.     where c1 > @min_identity and c1 <= @max_identity
  14852.     order by c1 asc
  14853.  
  14854.     --
  14855.     -- continue scripting
  14856.     --
  14857.     select @cmd = N'
  14858.                 if @@error != 0 
  14859.                     goto FAILURE
  14860.             end
  14861.         end '
  14862.     insert into #proctext(procedure_text) values (@cmd)
  14863.  
  14864.     if (@fisqueued = 1)
  14865.     begin
  14866.         select @cmd = N'
  14867.         else
  14868.         begin
  14869.             ' + N'--
  14870.             ' + N'-- handle queued cases
  14871.             ' + N'-- 
  14872.             if (@update_mode_id in (2,3))
  14873.             begin'
  14874.         insert into #proctext(procedure_text) values (@cmd)
  14875.  
  14876.         --
  14877.         -- MSMQ based write
  14878.         --
  14879.         select @cmd = N'
  14880.                 exec @retcode = master.dbo.sp_replsendtoqueue @queue_id, @tran_id, N' + 
  14881.             quotename(@publication, '''') + N', N' +    
  14882.             quotename(@cftproc, '''') + N', N' +
  14883.             quotename(@proc_owner, '''')    + N', N' + 
  14884.             quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  14885. '
  14886.         insert into #proctext(procedure_text) values (@cmd)
  14887.  
  14888.         --
  14889.         -- script the trigger variables
  14890.         --
  14891.         select @varindent = @indent + 8
  14892.         select @min_identity = @@identity
  14893.         if @op_type in ('ins', 'upd')
  14894.             exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @varindent, N'', 0,  @identity_col, @ts_col,
  14895.                 @no_output = 1
  14896.  
  14897.         if @op_type = 'upd'
  14898.         begin
  14899.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ',', 0, null, null,
  14900.                 @no_output = 1
  14901.  
  14902.             insert into #proctext(procedure_text) values (N'
  14903.                     ,@bitmap')
  14904.         end
  14905.  
  14906.         else if @op_type = 'del'
  14907.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ' ', 0, null, null,
  14908.                 @no_output = 1
  14909.  
  14910.         select @max_identity = @@identity
  14911.  
  14912.         --
  14913.         -- SQL Queued case
  14914.         -- we loop here if the command length exceeds queue message length and
  14915.         -- break the command into partial cmds and send it in more than one 
  14916.         -- queue message
  14917.         --
  14918.         select @cmd = N'
  14919.             end
  14920.             else if (@update_mode_id in (4,5))
  14921.             begin
  14922.                 select @partial_cmd = 1, @start_offset = 0, @end_offset = 0
  14923.                 while (@partial_cmd != 0)
  14924.                 begin'
  14925.         insert into #proctext(procedure_text) values (@cmd)
  14926.  
  14927.         select @cmd = N'
  14928.                     exec @retcode = master.dbo.sp_replwritetovarbin @start_offset, @end_offset output, @vb_buffer output, @vb_bufferlen output, N' + 
  14929.             quotename(@publisher, '''')    + N', N' +    
  14930.             quotename(@publisherdb, '''')    + N', N' +    
  14931.             quotename(@publication, '''')    + N', @tran_id, N' +    
  14932.             quotename(@cftproc, '''')    + N', N' +
  14933.             quotename(@proc_owner, '''')    + N', N' + 
  14934.             quotename(@procname, '''') + N', @subscriber, @subscriber_db, 
  14935. '
  14936.         insert into #proctext(procedure_text) values (@cmd)
  14937.  
  14938.         --
  14939.         -- script the trigger variables
  14940.         --
  14941.         select @min_identity = @@identity
  14942.         if @op_type in ('ins', 'upd')
  14943.             exec dbo.sp_MSscript_trigger_variables @objid, '@', N'', @varindent, N'', 0,  @identity_col, @ts_col,
  14944.                 @no_output = 1
  14945.  
  14946.         if @op_type = 'upd'
  14947.         begin
  14948.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ',', 0, null, null,
  14949.                 @no_output = 1
  14950.  
  14951.             insert into #proctext(procedure_text) values (N'
  14952.                     ,@bitmap')
  14953.         end
  14954.  
  14955.         else if @op_type = 'del'
  14956.             exec dbo.sp_MSscript_trigger_variables @objid, '@', '_old', @varindent, ' ', 0, null, null,
  14957.                 @no_output = 1
  14958.  
  14959.         select @max_identity = @@identity
  14960.  
  14961.         --
  14962.         -- continue scripting
  14963.         --
  14964.         select @cmd = N'
  14965.                     if @@error != 0 or @retcode != 0 
  14966.                     begin 
  14967.                         exec sp_MSreplraiserror 21052
  14968.                         goto FAILURE 
  14969.                     end'
  14970.         insert into #proctext(procedure_text) values(@cmd)
  14971.  
  14972.         --
  14973.         -- handle partial messages
  14974.         --
  14975.         select @object_owner = user_name(ObjectProperty(@objid, 'ownerid'))
  14976.         select @cmd = N'
  14977.                     select @partial_cmd = case when (@end_offset > 0) then 1 else 0 end            
  14978.                     exec @retcode = sp_MSsendtosqlqueue @@procid, N' + 
  14979.                         quotename(@publisher, '''') + N', N' + 
  14980.                         quotename(@publisherdb, '''') + N', N' + 
  14981.                         quotename(@publication, '''') + N', N' +
  14982.                         quotename(@object_owner, '''') +
  14983.                         N', @tran_id, @vb_buffer, @vb_bufferlen, 1, @partial_cmd '
  14984.         insert into #proctext(procedure_text) values(@cmd)
  14985.  
  14986.         --
  14987.         -- continue scripting
  14988.         --
  14989.         select @cmd = N'
  14990.                     if @@error != 0 or @retcode != 0 
  14991.                     begin 
  14992.                         exec sp_MSreplraiserror 21052
  14993.                         goto FAILURE 
  14994.                     end
  14995.                     select @start_offset = @end_offset
  14996.                 end
  14997.             end'
  14998.         insert into #proctext(procedure_text) values(@cmd)
  14999.  
  15000.         --
  15001.         -- continue scripting
  15002.         --
  15003.         select @cmd = N'
  15004.             if @@error <>0 or @retcode <> 0 
  15005.             begin 
  15006.                 exec sp_MSreplraiserror 21052
  15007.                 goto FAILURE 
  15008.             end
  15009.         end
  15010.     '
  15011.         insert into #proctext(procedure_text) values(@cmd)
  15012.     end
  15013.     
  15014.     --
  15015.     -- all done
  15016.     --
  15017.     return 0
  15018. END
  15019. go
  15020.  
  15021. raiserror('Creating procedure sp_MSscript_trigger_update_checks', 0,1)
  15022. go
  15023.  
  15024. create procedure sp_MSscript_trigger_update_checks(
  15025.     @objid int,
  15026.     @identity_col sysname,
  15027.     @ts_col       sysname,
  15028.     @op_type varchar(3) = 'ins', -- 'ins', 'upd'
  15029.     @indent int = 0
  15030. )
  15031. as
  15032. BEGIN
  15033.     declare @cmd          nvarchar(4000)
  15034.     declare @colname      sysname
  15035.     declare @ccoltype     sysname
  15036.     declare @src_cols     int
  15037.     declare @this_col     int
  15038.     declare @rc           int
  15039.     declare @qualname     nvarchar(512)
  15040.     declare @indid        int
  15041.     declare @key          sysname
  15042.     declare @indkey       int
  15043.  
  15044. /*
  15045.     if @op_type = 'pk'
  15046.     begin
  15047.         select @indkey = 1
  15048.         exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15049.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  15050.         if @indid > 0
  15051.           begin
  15052.             exec dbo.sp_MSpad_command @cmd output, @indent
  15053.             while @indkey < 16 and index_col(@qualname, @indid, @indkey) is not null
  15054.             begin
  15055.                 select @key = index_col(@qualname, @indid, @indkey)
  15056.                 select @cmd = N'if update(' + @key + N')
  15057. '
  15058.                 exec dbo.sp_MSflush_command @cmd output, 1, @indent
  15059.                 insert into #proctext(procedure_text) values(N'begin
  15060.      exec sp_MSreplraiserror 20517
  15061.      goto FAILURE
  15062.  end 
  15063.  
  15064. ')
  15065.                 select @indkey = @indkey + 1
  15066.             end
  15067.         end
  15068.     end
  15069.     else
  15070.     begin
  15071.  */
  15072.     -- Image cols
  15073.     select @src_cols = max(colid) from syscolumns where id = @objid
  15074.     select @this_col = 1
  15075.     exec dbo.sp_MSpad_command @cmd output, @indent
  15076.    
  15077.         while @this_col <= @src_cols
  15078.         begin
  15079.             exec @rc = dbo.sp_MSget_colinfo @objid, @this_col, null, 1, @colname output, @ccoltype output
  15080.             if @rc = 0  and EXISTS (select name from syscolumns where id=@objid and @this_col=colid and iscomputed<>1)
  15081.             begin
  15082.                 if @ccoltype in ('text','ntext','image')
  15083.                 begin
  15084.                 if @op_type = 'ins'
  15085.                     begin
  15086.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  15087. '
  15088.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  15089.                         insert into #proctext(procedure_text) values(N'    exec sp_MSreplraiserror 20508
  15090. ')
  15091.                     end
  15092.                     else if @op_type = 'upd'
  15093.                     begin
  15094.                         select @cmd = N'if update(' +  quotename(@colname) + ') 
  15095.                         exec dbo.sp_MSflush_command @cmd output, 1, 0
  15096.                         insert into #proctext(procedure_text) values(N'begin
  15097.      exec sp_MSreplraiserror 20509
  15098.      goto FAILURE 
  15099.  end
  15100.  
  15101. ')
  15102.                     end
  15103.                 end
  15104.             end
  15105.             select @this_col = @this_col + 1
  15106.         end
  15107.  --   end
  15108.  
  15109.     -- identity col
  15110.     if @op_type = 'upd' and @identity_col is not null
  15111.     begin
  15112.         select @cmd = N'if update(' +  quotename(@identity_col) + N') 
  15113. '
  15114.         exec dbo.sp_MSflush_command @cmd, 1
  15115.         insert into #proctext(procedure_text) values(N'begin
  15116.      exec sp_MSreplraiserror 20510
  15117.      goto FAILURE
  15118.  end
  15119.  
  15120. ')
  15121.     end
  15122.  
  15123.     -- timestamp col
  15124.     if @op_type = 'upd' and @ts_col is not null
  15125.     begin
  15126.         select @cmd = N'if update(' +  quotename(@ts_col) + N') 
  15127. '
  15128.         exec dbo.sp_MSflush_command @cmd, 1
  15129.         insert into #proctext(procedure_text) values(N'begin
  15130.      exec sp_MSreplraiserror 20511
  15131.      goto FAILURE
  15132.  end
  15133.  
  15134. ')
  15135.     end
  15136. END
  15137. go    
  15138.  
  15139. raiserror('Creating procedure sp_MSscript_trigger_updates', 0,1)
  15140. go
  15141. create procedure sp_MSscript_trigger_updates
  15142.     @identity_col sysname,
  15143.     @ts_col       sysname,
  15144.     @op_type      char(3) = 'ins', -- 'ins', 'del'
  15145.     @objid        int,
  15146.     @indent       int = 0,
  15147.     @primary_key_bitmap varbinary(4000) = null
  15148. as
  15149.     declare @cmd nvarchar(4000)
  15150.     declare @col sysname
  15151.     declare @qualname nvarchar(512)
  15152.  
  15153.     if @op_type = 'upd'
  15154.     begin
  15155.         -- Script out pk var assigment that used in sp_MSscript_where_clause
  15156.         exec dbo.sp_MSscript_pkvar_assignment @objid, NULL, 1, @identity_col, @ts_col, 
  15157.             @primary_key_bitmap
  15158.  
  15159.         insert into #proctext(procedure_text) values(N'
  15160.     ')
  15161.     end
  15162.  
  15163.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15164.  
  15165.     if @ts_col is not null and OBJECTPROPERTY(@objid, 'tablehastimestamp') <> 1
  15166.     begin
  15167.         insert into #proctext(procedure_text) values(N' 
  15168. ')
  15169.         exec dbo.sp_MSpad_command @cmd output, @indent
  15170.         exec dbo.sp_MSget_col_position @objid, null, @ts_col, @col output
  15171.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @ts_col + N' = @' + @col
  15172.         exec dbo.sp_MSflush_command @cmd, 1
  15173.  
  15174.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type, @primary_key_bitmap
  15175.     end
  15176.  
  15177.    -- Reset to publisher's identity value if it is not an identity at the subscriber
  15178.    if @op_type = 'ins' and @identity_col is not null and OBJECTPROPERTY(@objid, 'tablehasidentity') <> 1
  15179.     begin
  15180.         insert into #proctext(procedure_text) values(N' 
  15181. ')
  15182.         exec dbo.sp_MSpad_command @cmd output, @indent
  15183.         exec dbo.sp_MSget_col_position @objid, null, @identity_col, @col output
  15184.         select @cmd = @cmd + N'update ' + @qualname + N' set ' + @identity_col + N' = @' + @col
  15185.         exec dbo.sp_MSflush_command @cmd, 1
  15186.  
  15187.         exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, @op_type, @primary_key_bitmap
  15188.     end
  15189. go
  15190.  
  15191. raiserror('Creating procedure sp_MSscript_trigger_version_updates', 0,1)
  15192. go
  15193. create procedure sp_MSscript_trigger_version_updates
  15194.     @objid        int,
  15195.     @version_col  sysname,
  15196.     @indent       int = 0,
  15197.     @primary_key_bitmap   varbinary(4000)
  15198. as
  15199.     declare @cmd nvarchar(4000)
  15200.     declare @col sysname
  15201.     declare @qualname nvarchar(512)
  15202.  
  15203.     -- Script out pk var assigment that used in sp_MSscript_where_clause
  15204.     exec dbo.sp_MSscript_pkvar_assignment @objid, NULL, 1, null, null, @primary_key_bitmap
  15205.  
  15206.     insert into #proctext(procedure_text) values(N'
  15207. ')
  15208.  
  15209.     exec dbo.sp_MSget_col_position @objid, null, @version_col, @col output
  15210.  
  15211.     -- Assign the param corresponding to version col to new guid
  15212.     exec dbo.sp_MSpad_command @cmd output, @indent
  15213.     select @cmd = @cmd + N'set @' + @col + N' = @version_guid ' 
  15214.     exec dbo.sp_MSflush_command @cmd, 1
  15215.     insert into #proctext(procedure_text) values(N' 
  15216. ')
  15217.  
  15218.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15219.     exec dbo.sp_MSpad_command @cmd output, @indent
  15220.     select @cmd = N'update ' + @qualname + N' set ' + @version_col + N' = @' + @col
  15221.     exec dbo.sp_MSflush_command @cmd, 1
  15222.     exec dbo.sp_MSscript_where_clause @objid, null, 'trg pk', null, @indent, 'upd', @primary_key_bitmap
  15223. go
  15224.  
  15225. raiserror('Creating procedure sp_MSscript_singlerow_trigger', 0,1)
  15226. go
  15227. create procedure sp_MSscript_singlerow_trigger (
  15228.     @objid        int,
  15229.     @publisher    sysname,
  15230.     @publisher_db sysname,
  15231.     @publication  sysname,
  15232.     @procname     sysname,
  15233.     @proc_owner      sysname,
  15234.     @cftproc      sysname,
  15235.     @identity_col  sysname,
  15236.     @ts_col        sysname,
  15237.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  15238.     @primary_key_bitmap varbinary(4000) = NULL
  15239. )
  15240. as
  15241. BEGIN
  15242.     declare @colname      sysname
  15243.             ,@spacer       nvarchar(1)
  15244.             ,@ccoltype     sysname
  15245.             ,@this_col     int
  15246.             ,@rc           int
  15247.             ,@cmd            nvarchar(4000)
  15248.  
  15249.     --
  15250.     -- script update checks
  15251.     --
  15252.     if @op_type in ('ins', 'upd')
  15253.         exec dbo.sp_MSscript_trigger_update_checks @objid, @identity_col, @ts_col, @op_type, 0
  15254.  
  15255.     --
  15256.     -- continue scripting
  15257.     --
  15258.     select @cmd = N' 
  15259.     ' + N'--
  15260.     ' + N'-- Are we doing single or multi row trigger update 
  15261.     ' + N'--
  15262.     if (@rc = 1)
  15263.     begin 
  15264.         ' + N'--
  15265.         ' + N'-- single row trigger update
  15266.         ' + N'-- '
  15267.     insert into #proctext(procedure_text) values(@cmd)
  15268.  
  15269.     --
  15270.     -- script the trigger assignments
  15271.     --
  15272.     if @op_type in ('ins', 'upd')
  15273.     begin
  15274.         select @cmd = N'
  15275.         select 
  15276. '
  15277.         insert into #proctext(procedure_text) values(@cmd)
  15278.         exec dbo.sp_MSscript_trigger_assignment @objid, null, 8, @ts_col, @op_type, 1, @primary_key_bitmap
  15279.         select @cmd = N'
  15280.         from inserted '
  15281.         insert into #proctext(procedure_text) values(@cmd)    
  15282.     end
  15283.  
  15284.     if @op_type in ('ins')
  15285.     begin
  15286.         select @cmd = N'
  15287.         select 
  15288. '
  15289.         insert into #proctext(procedure_text) values(@cmd)
  15290.         exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 8, @ts_col, @op_type, 0, @primary_key_bitmap
  15291.         select @cmd = N'
  15292.         from inserted '
  15293.         insert into #proctext(procedure_text) values(@cmd)    
  15294.     end
  15295.     else if @op_type in ('upd', 'del')
  15296.     begin
  15297.         select @cmd = N'
  15298.         select 
  15299. '
  15300.         insert into #proctext(procedure_text) values(@cmd)
  15301.         exec dbo.sp_MSscript_trigger_assignment @objid, '_old', 8, @ts_col, @op_type, 0, @primary_key_bitmap
  15302.         select @cmd = N'
  15303.         from deleted '
  15304.         insert into #proctext(procedure_text) values(@cmd)    
  15305.     end
  15306.  
  15307.     --
  15308.     -- script the execution logic
  15309.     --
  15310.     exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15311.                 @cftproc, @objid, @op_type, 12, @identity_col, @ts_col, @primary_key_bitmap
  15312.             
  15313.     --
  15314.     -- script any updates to be done
  15315.     --
  15316.     if @op_type in ('ins', 'upd')
  15317.         exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 8, @primary_key_bitmap
  15318.  
  15319.     --
  15320.     -- script the end (for single row change)
  15321.     -- 
  15322.     select @cmd = N'
  15323.     end -- end of single row trigger update '
  15324.     insert into #proctext(procedure_text) values(@cmd)
  15325.  
  15326.     --
  15327.     -- all done
  15328.     --
  15329.     return 0
  15330. END
  15331. go
  15332.  
  15333. raiserror('Creating procedure sp_MSscript_multirow_trigger', 0,1)
  15334. go
  15335. create procedure sp_MSscript_multirow_trigger (
  15336.     @objid        int,
  15337.     @publisher    sysname,
  15338.     @publisher_db sysname,
  15339.     @publication  sysname,
  15340.     @procname     sysname,
  15341.     @proc_owner      sysname,
  15342.     @cftproc      sysname,
  15343.     @identity_col  sysname,
  15344.     @ts_col        sysname,
  15345.     @op_type char(3) = 'ins', -- 'ins, 'upd', 'del'
  15346.     @primary_key_bitmap varbinary(4000) = NULL
  15347. )
  15348. as
  15349. BEGIN
  15350.  
  15351.     declare @cmd          nvarchar(4000)
  15352.  
  15353.     --
  15354.     -- start scripting
  15355.     --
  15356.     select @cmd = N'
  15357.     else
  15358.     begin 
  15359.         ' + N'--
  15360.         ' + N'-- start of multirow row trigger update 
  15361.         ' + N'-- '
  15362.     insert into #proctext(procedure_text) values(@cmd)
  15363.  
  15364.     --
  15365.     -- setup cursor over inserted table for ins & upd triggers
  15366.     --
  15367.     if @op_type in ('ins', 'upd')
  15368.     begin
  15369.         select @cmd = N'
  15370.         declare rpl_ins_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  15371. '
  15372.         insert into #proctext(procedure_text) values(@cmd)
  15373.  
  15374.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' ',
  15375.             0,@identity_col, @ts_col,0, 1, @op_type, 1, @primary_key_bitmap
  15376.  
  15377.         select @cmd = N'
  15378.         from inserted for read only
  15379.         open rpl_ins_cursor 
  15380. '
  15381.         insert into #proctext(procedure_text) values(@cmd)
  15382.     end
  15383.  
  15384.     if @op_type in ('ins')
  15385.     begin
  15386.         select @cmd = N'
  15387.         declare rpl_ins2_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  15388. '
  15389.         insert into #proctext(procedure_text) values(@cmd)
  15390.  
  15391.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' '
  15392.  
  15393.         select @cmd = N'
  15394.         from inserted for read only
  15395.         open rpl_ins2_cursor 
  15396. '
  15397.         insert into #proctext(procedure_text) values(@cmd)
  15398.     end
  15399.  
  15400.     --
  15401.     -- setup cursor over deleted table for  upd & del triggers
  15402.     --
  15403.     if @op_type in ('upd', 'del')
  15404.     begin
  15405.         select @cmd = N'
  15406.         declare rpl_del_cursor CURSOR LOCAL FAST_FORWARD FOR select 
  15407. '
  15408.         insert into #proctext(procedure_text) values(@cmd)
  15409.  
  15410.         exec dbo.sp_MSscript_trigger_variables @objid, null, null, 8, ' ', 
  15411.             0,@identity_col, @ts_col,0, 1,  @op_type, 0, @primary_key_bitmap
  15412.  
  15413.         select @cmd = N'
  15414.         from deleted for read only
  15415.         open rpl_del_cursor 
  15416. '
  15417.         insert into #proctext(procedure_text) values(@cmd)
  15418.     end
  15419.  
  15420.     --
  15421.     -- script fetch statement
  15422.     --
  15423.     exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 8
  15424.  
  15425.     --
  15426.     -- start the fetch loop
  15427.     --
  15428.     select @cmd = N'
  15429.         while (@@fetch_status != -1)
  15430.         begin '
  15431.     insert into #proctext(procedure_text) values(@cmd)
  15432.  
  15433.     --
  15434.     -- script the execution logic
  15435.     --
  15436.     exec dbo.sp_MSscript_trigger_exec_rpc @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15437.             @cftproc, @objid, @op_type, 16, @identity_col, @ts_col, @primary_key_bitmap
  15438.  
  15439.     --
  15440.     -- script any updates to be done
  15441.     --
  15442.     if @op_type in ('ins', 'upd')
  15443.         exec dbo.sp_MSscript_trigger_updates @identity_col, @ts_col, @op_type, @objid, 8, @primary_key_bitmap
  15444.  
  15445.     --
  15446.     -- do the next fetch
  15447.     --
  15448.     insert into #proctext(procedure_text) values(N'
  15449. ')
  15450.     exec dbo.sp_MSscript_trigger_fetch_statement @objid, @op_type, 12
  15451.  
  15452.     --
  15453.     -- release the cursors
  15454.     --
  15455.     select @cmd = N'
  15456.         end  -- cursor while loop'
  15457.     insert into #proctext(procedure_text) values(@cmd)
  15458.  
  15459.     if @op_type in ('ins', 'upd')
  15460.     begin
  15461.         select @cmd = N'
  15462.         close rpl_ins_cursor
  15463.         deallocate rpl_ins_cursor '
  15464.         insert into #proctext(procedure_text) values(@cmd)
  15465.     end
  15466.  
  15467.     if @op_type = 'ins'
  15468.     begin
  15469.         select @cmd = N'
  15470.         close rpl_ins2_cursor
  15471.         deallocate rpl_ins2_cursor '
  15472.         insert into #proctext(procedure_text) values(@cmd)
  15473.     end
  15474.  
  15475.     if @op_type in ('upd', 'del')
  15476.     begin
  15477.         select @cmd = N'
  15478.         close rpl_del_cursor
  15479.         deallocate rpl_del_cursor '
  15480.         insert into #proctext(procedure_text) values(@cmd)        
  15481.     end
  15482.  
  15483.     --
  15484.     -- script the end (for single row change)
  15485.     -- 
  15486.     select @cmd = N'
  15487.     end -- end of multi row trigger update '
  15488.     insert into #proctext(procedure_text) values(@cmd)
  15489.  
  15490.     --
  15491.     -- all done
  15492.     --
  15493.     return 0
  15494.  
  15495. END
  15496. go
  15497.  
  15498. raiserror('Creating procedure sp_MSscript_sync_ins_trig', 0,1)
  15499. go
  15500. create procedure sp_MSscript_sync_ins_trig (
  15501.     @objid          int,
  15502.     @publisher    sysname,
  15503.     @publisher_db sysname,
  15504.     @publication  sysname,
  15505.     @trigname     sysname,
  15506.     @procname     sysname,
  15507.     @proc_owner   sysname,
  15508.     @cftproc      sysname,
  15509.     @agent_id      int, 
  15510.     @identity_col sysname = NULL,
  15511.     @ts_col       sysname = NULL,
  15512.     @filter_clause nvarchar(4000),
  15513.     @primary_key_bitmap  varbinary(4000)
  15514. )
  15515. as
  15516. BEGIN
  15517.     declare @colname      sysname
  15518.             ,@cmd          nvarchar(4000)
  15519.             ,@ins_cmd      nvarchar(4000)
  15520.             ,@columns      binary(32)
  15521.             ,@outvars      nvarchar(4000)
  15522.             ,@rc           int
  15523.             ,@qualname     nvarchar(512)
  15524.             ,@fisqueued       bit
  15525.  
  15526.     set nocount on
  15527.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15528.     if (LOWER(@cftproc) = N'null')
  15529.     begin
  15530.         select @fisqueued =  0
  15531.                 ,@cftproc = NULL
  15532.     end
  15533.     else 
  15534.         select @fisqueued =  1
  15535.  
  15536.     if @ts_col in ('null','NULL')
  15537.         select @ts_col = null
  15538.  
  15539.     if @identity_col in ('null','NULL')
  15540.         select @identity_col = null
  15541.  
  15542.     -- Create temp table
  15543.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  15544.  
  15545.     -- 1st preamble common to all synctran procs
  15546.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'ins', @fisqueued
  15547.                 
  15548.     -- 2nd preamble common to all synctran procs
  15549.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'ins',@agent_id, @fisqueued
  15550.  
  15551.     -- script single row handling
  15552.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15553.         @cftproc, @identity_col, @ts_col, 'ins', @primary_key_bitmap
  15554.  
  15555.     -- script multi-row handling
  15556.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid, @publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15557.         @cftproc, @identity_col, @ts_col, 'ins', @primary_key_bitmap
  15558.  
  15559.     -- script end of trigger
  15560.     exec dbo.sp_MSscript_endtrig 
  15561.  
  15562.     -- send fragments to client
  15563.     select procedure_text from #proctext order by c1 asc
  15564. END
  15565. go
  15566.  
  15567. raiserror('Creating procedure sp_MSscript_sync_upd_trig', 0,1)
  15568. go
  15569. create procedure sp_MSscript_sync_upd_trig (
  15570.     @objid        int,
  15571.     @publisher    sysname,
  15572.     @publisher_db sysname,
  15573.     @publication  sysname, 
  15574.     @trigname     sysname,
  15575.     @procname     sysname,
  15576.     @proc_owner   sysname,
  15577.     @cftproc      sysname,
  15578.     @agent_id      int, 
  15579.     @identity_col sysname = NULL,
  15580.     @ts_col       sysname = NULL,
  15581.     @filter_clause nvarchar(4000),
  15582.     @primary_key_bitmap  varbinary(4000) )
  15583. as
  15584. BEGIN
  15585.     declare @colname      sysname
  15586.             ,@cmd          nvarchar(4000)
  15587.             ,@ins_cmd      nvarchar(4000)
  15588.             ,@columns      binary(32)
  15589.             ,@outvars      nvarchar(4000)
  15590.             ,@rc           int
  15591.             ,@qualname     nvarchar(512)
  15592.             ,@fisqueued       bit
  15593.  
  15594.     set nocount on
  15595.  
  15596.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15597.     if (LOWER(@cftproc) = N'null')
  15598.     begin
  15599.         select @fisqueued =  0
  15600.                 ,@cftproc = NULL
  15601.     end
  15602.     else 
  15603.         select @fisqueued =  1
  15604.  
  15605.     if @ts_col in ('null','NULL')
  15606.         select @ts_col = null
  15607.  
  15608.     if @identity_col in ('null','NULL')
  15609.         select @identity_col = null
  15610.  
  15611.     -- Create temp table
  15612.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  15613.  
  15614.     -- 1st preamble common to all synctran procs
  15615.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'upd', @fisqueued
  15616.                     
  15617.     -- prevent updating of unique index when 'row compare' conflict detection, since it would trickle
  15618.     -- back as a del/insert, and fail
  15619. /*
  15620.     if @ts_col is null
  15621.     begin
  15622.         insert into #proctext(procedure_text) values(N' 
  15623. ')
  15624. --        exec dbo.sp_MSscript_trigger_update_checks @objid, null, null, 'pk', 0
  15625.     end
  15626. */
  15627.  
  15628.     -- 2nd preamble common to all synctran procs
  15629.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'upd',@agent_id, @fisqueued
  15630.  
  15631.     -- script single row handling
  15632.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15633.         @cftproc, @identity_col, @ts_col, 'upd', @primary_key_bitmap
  15634.  
  15635.     -- script multi-row handling
  15636.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15637.         @cftproc, @identity_col, @ts_col, 'upd', @primary_key_bitmap
  15638.     -- script end of trigger
  15639.     exec dbo.sp_MSscript_endtrig 
  15640.  
  15641.     -- send fragments to client
  15642.     select procedure_text from #proctext order by c1 asc
  15643. END
  15644. go
  15645.  
  15646. raiserror('Creating procedure sp_MSscript_sync_del_trig', 0,1)
  15647. go
  15648. create procedure sp_MSscript_sync_del_trig (
  15649.     @objid        int,
  15650.     @publisher    sysname,
  15651.     @publisher_db sysname,
  15652.     @publication  sysname, 
  15653.     @trigname     sysname,
  15654.     @procname     sysname,
  15655.     @proc_owner      sysname,
  15656.     @cftproc      sysname,
  15657.     @agent_id      int, 
  15658.     @identity_col sysname = NULL,
  15659.     @ts_col       sysname = NULL,
  15660.     @filter_clause nvarchar(4000),
  15661.     @primary_key_bitmap  varbinary(4000)
  15662. )
  15663. as
  15664. BEGIN
  15665.     declare @colname sysname
  15666.             ,@cmd          nvarchar(4000)
  15667.             ,@ins_cmd      nvarchar(4000)
  15668.             ,@columns      binary(32)
  15669.             ,@outvars      nvarchar(4000)
  15670.             ,@rc           int
  15671.             ,@qualname     nvarchar(512)
  15672.             ,@fisqueued       bit
  15673.  
  15674.     set nocount on
  15675.  
  15676.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  15677.     if (LOWER(@cftproc) = N'null')
  15678.     begin
  15679.         select @fisqueued =  0
  15680.                 ,@cftproc = NULL
  15681.     end
  15682.     else 
  15683.         select @fisqueued =  1
  15684.  
  15685.     if @ts_col in ('null','NULL')
  15686.         select @ts_col = null
  15687.  
  15688.     if @identity_col in ('null','NULL')
  15689.         select @identity_col = null
  15690.  
  15691.     -- Create temp table
  15692.     create table #proctext ( c1 int identity NOT NULL, procedure_text nvarchar(4000) collate database_default null)
  15693.  
  15694.     -- 1st preamble common to all synctran procs
  15695.     exec dbo.sp_MSscript_begintrig1 @trigname, @objid, @procname, @filter_clause, 'del', @fisqueued
  15696.  
  15697.     -- 2nd preamble common to all synctran procs
  15698.     exec dbo.sp_MSscript_begintrig2 @publisher, @publisher_db, @publication, @objid, 'del', @agent_id, @fisqueued
  15699.  
  15700.     -- script single row handling
  15701.     exec @rc = dbo.sp_MSscript_singlerow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15702.     @cftproc, @identity_col, @ts_col, 'del', @primary_key_bitmap
  15703.  
  15704.     -- script multi-row handling
  15705.     exec @rc = dbo.sp_MSscript_multirow_trigger @objid,@publisher, @publisher_db, @publication, @procname, @proc_owner, 
  15706.     @cftproc, @identity_col, @ts_col, 'del', @primary_key_bitmap
  15707.  
  15708.     -- script end of trigger
  15709.     exec dbo.sp_MSscript_endtrig 
  15710.  
  15711.     -- send fragments to client
  15712.     select procedure_text from #proctext order by c1 asc
  15713. END
  15714. go
  15715.  
  15716. raiserror('Creating procedure sp_MSget_synctran_column', 0,1)
  15717. go
  15718. create procedure sp_MSget_synctran_column
  15719. (
  15720.     @ts_col sysname,
  15721.     @op_type char(3), -- 'ins, 'upd', 'del'
  15722.     @is_new    bit,
  15723.     @primary_key_bitmap varbinary(4000) = null,
  15724.     @colname sysname,
  15725.     @this_col int, -- position in source object
  15726.     @column nvarchar(4000) output,
  15727.     @from_proc bit = 0,
  15728.     @coltype sysname = NULL,
  15729.     @type    varchar(10) = NULL,
  15730.     @art_col int = NULL -- position in the partition.
  15731. )
  15732. as
  15733. begin
  15734.     declare @bytestr      nvarchar(10)
  15735.             ,@bitstr       nvarchar(10)
  15736.             ,@typed_null      nvarchar(255)
  15737.  
  15738.     --
  15739.     -- if @art_col is not NULL then it means one of the following:
  15740.     -- 1) If we are scripting for triggers - then it means the subscriber
  15741.     --     table (destination table) was altered and column id do not match
  15742.     --     relative column order(as specified in PK bitmap or columns_updated()).
  15743.     --    The @art_col will represent the relative column order in the bitmap
  15744.     --    and @this_col will represent the actual column id
  15745.     --
  15746.     -- 2) If we are scripting for synctran procedures on publisher - then 
  15747.     --    @art_col represents the relative index of the column that is being
  15748.     --    replicated and @this_col represents the actual column id of the column
  15749.     --
  15750.     -- if @art_col is NULL - then we will set it to the value of @this_col
  15751.     --
  15752.     if (@art_col is NULL)
  15753.         select @art_col = @this_col
  15754.         
  15755.     select @typed_null = case when (@coltype is null) then N'NULL'
  15756.                     else N'convert(' + @coltype + N', NULL)' end
  15757.  
  15758.     -- Optimization:
  15759.     -- If the column value is not needed, we set the corresponding
  15760.     -- param to null to reduce the network traffic. Here is the rule:
  15761.  
  15762.     -- For new values in update trigger,
  15763.     --    Set the param to column value or null depending on whether or
  15764.     --  or the column is updated.
  15765.     -- For old values 
  15766.     --    if ts col is replicated and the current column is not the ts col
  15767.     --    and the column is not in primary key, set the param to null
  15768.     -- For other cases
  15769.     --    set the param to column values.
  15770.  
  15771.     -- Called by proc
  15772.     if @type = 'pk_var'
  15773.     begin
  15774.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  15775.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  15776.  
  15777.         select @column = N'case substring(@bitmap,' 
  15778.             + @bytestr + N',1) & ' + @bitstr +  
  15779.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  15780.             N' else ' + N'@c'+ convert( nvarchar, @this_col )  + N'_old end'
  15781.     end
  15782.     else if (@from_proc = 1)
  15783.     begin
  15784.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  15785.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  15786.  
  15787.         select @column = N'case substring(@bitmap,' 
  15788.             + @bytestr + N',1) & ' + @bitstr +  
  15789.             N' when ' + @bitstr + N' then ' + N'@c'+ convert( nvarchar, @this_col ) + 
  15790.             N' else [' + @colname + N'] end'
  15791.     end
  15792.     -- Called in trigger,
  15793.     else if (@is_new = 1) and (@op_type = 'upd')
  15794.     begin
  15795.         -- @bitmap is set using columns_updated() at the beginning
  15796.         -- of the trigger.
  15797.         select @bytestr = convert( nvarchar, 1 + (@art_col-1) / 8 )
  15798.         select @bitstr =  convert( nvarchar, power(2, (@art_col-1) % 8 ) )
  15799.         
  15800.         select @column = N'case substring(@bitmap,' + @bytestr + N',1) & ' + @bitstr +  
  15801.             N' when ' + @bitstr + N' then [' + @colname + N'] ' + 
  15802.             N' else ' + @typed_null 
  15803.             +' end'
  15804.     end
  15805.     else if ((@is_new = 0) and 
  15806.         (@ts_col is not null and @colname not in (@ts_col, N'msrepl_tran_version')) and
  15807.         (@primary_key_bitmap is not null and 
  15808.         (substring(@primary_key_bitmap, 1 + (@art_col-1) / 8 , 1) & power(2, (@art_col-1) % 8 )) = 0))
  15809.         select @column =  @typed_null
  15810.     else 
  15811.         select @column = N'[' + @colname  + N'] '
  15812.     
  15813.     -- Add a new line
  15814.     select @column = @column + N'
  15815.     '
  15816. end
  15817. go
  15818.  
  15819. --
  15820. -- proc that is invoked by distribution agent to populate
  15821. -- MSsubscription_articles with all the necessary article
  15822. -- this is done currently only for queued publications 
  15823. --
  15824. raiserror('Creating procedure sp_addqueued_artinfo', 0,1)
  15825. go
  15826.  
  15827. CREATE PROCEDURE sp_addqueued_artinfo (
  15828.     @artid                int
  15829.     ,@article            sysname
  15830.     ,@publisher         sysname
  15831.     ,@publisher_db        sysname
  15832.     ,@publication        sysname
  15833.     ,@dest_table        sysname
  15834.     ,@owner                sysname
  15835.     ,@cft_table            sysname
  15836.     ,@columns            binary(32))
  15837. AS
  15838. BEGIN
  15839.     set nocount on
  15840.     declare     @agent_id int
  15841.                 ,@update_mode int
  15842.                 ,@retcode int
  15843.  
  15844.     --
  15845.     -- Create system table MSsubscription_articles if it does not exist
  15846.     --
  15847.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  15848.         type = 'U' AND name = 'MSsubscription_articles')
  15849.     BEGIN
  15850.         CREATE TABLE dbo.MSsubscription_articles
  15851.         (
  15852.             agent_id        int NOT NULL,        -- related entry in MSsubscription_agents
  15853.             artid            int NOT NULL,        -- article id
  15854.             article            sysname,            -- article name
  15855.             dest_table        sysname,            -- destination table
  15856.             owner            sysname,
  15857.             cft_table        sysname,            -- conflict table
  15858.             columns            binary(32)
  15859.         )
  15860.         IF (@@ERROR != 0)
  15861.         begin
  15862.             raiserror('Debug:sp_addqueued_artinfo - create MSsubscription_articles failed', 16, 1)
  15863.             return (1)
  15864.         end
  15865.  
  15866.         CREATE UNIQUE CLUSTERED INDEX ucMSsubscription_articles ON dbo.MSsubscription_articles(agent_id, artid)
  15867.         IF (@@ERROR != 0)
  15868.         begin
  15869.             raiserror('Debug:sp_addqueued_artinfo - create index for MSsubscription_articles failed', 16, 1)
  15870.             return (1)
  15871.         end
  15872.         
  15873.         EXEC dbo.sp_MS_marksystemobject 'MSsubscription_articles'
  15874.     END
  15875.  
  15876.     --
  15877.     -- insert the row for the given article
  15878.     --
  15879.     select @agent_id = id, @update_mode = update_mode
  15880.     from MSsubscription_agents 
  15881.     where UPPER(publisher) = UPPER(@publisher) and 
  15882.         publisher_db = @publisher_db and 
  15883.         publication = @publication 
  15884.  
  15885.     if (@agent_id IS NULL)
  15886.     begin
  15887.         raiserror('Debug:sp_addqueued_artinfo - agent_id is null for [%s].[%s].[%s]', 
  15888.             16, 1, @publisher, @publisher_db, @publication)
  15889.         return (1)
  15890.     end
  15891.  
  15892.     -- If the subscription is read only or immediate, no need to article info.
  15893.     if @update_mode in (0,1)
  15894.         return 0
  15895.  
  15896.     --
  15897.     -- If MSMQ Queued mode - check if the subscriber is compliant for MSMQ 2.0
  15898.     --
  15899.     if (@update_mode in (2,3))
  15900.     begin
  15901.         if ((platform() & 0x1) != 0x1)
  15902.         begin
  15903.             --
  15904.             -- Win 9X platform
  15905.             --
  15906.             raiserror(21334, 16, 1, '2.0')
  15907.             return (1)
  15908.         end
  15909.  
  15910.         --
  15911.         -- Now we use xp_MSver to detect NT OS version
  15912.         -- MSMQ subscription only allowed for platforms that support MSMQ 2.0
  15913.         -- version 5.0.2195 or higher
  15914.         --
  15915.         create table #tosversion ( propid int, propname sysname collate database_default, value int, charvalue nvarchar(255) collate database_default)
  15916.         insert into #tosversion (propid, propname, value, charvalue)
  15917.             exec master.dbo.xp_msver N'WindowsVersion'
  15918.  
  15919.         declare @vervalue int
  15920.             ,@lobyte tinyint
  15921.             ,@hibyte tinyint
  15922.             ,@loword smallint
  15923.             ,@hiword smallint
  15924.  
  15925.         --
  15926.         -- low order byte of low order word = OSmajor, high order byte of low order word = OSminor
  15927.         -- high order word = OSbuild
  15928.         --
  15929.         select @vervalue = value from #tosversion where propname = N'WindowsVersion'
  15930.         select @loword = (@vervalue & 0xffff)
  15931.                 ,@hiword = (@vervalue / 0x10000) & 0xffff
  15932.         select @lobyte = @loword & 0xff
  15933.                 ,@hibyte = (@loword / 100) & 0xff
  15934.         drop table #tosversion
  15935.  
  15936.         --
  15937.         -- check for OS major version
  15938.         --
  15939.         if (@lobyte < 5)
  15940.         begin
  15941.             raiserror(21334, 16, 2, '2.0')
  15942.             return (1)
  15943.         end
  15944.  
  15945.         --
  15946.         -- check for OS build version
  15947.         --
  15948.         if (@lobyte = 5 and @hiword < 2195)
  15949.         begin
  15950.             raiserror(21334, 16, 3, '2.0')
  15951.             return (1)
  15952.         end
  15953.     end
  15954.  
  15955.     --
  15956.     -- Check for owner - use current user for NULL value
  15957.     --
  15958.     if (@owner IS NULL or lower(@owner) = N'null' collate database_default)
  15959.         select @owner = user_name()
  15960.  
  15961.     if exists (select * from MSsubscription_articles where agent_id = @agent_id and artid = @artid)
  15962.         delete MSsubscription_articles where agent_id = @agent_id and artid = @artid
  15963.         
  15964.     insert into MSsubscription_articles(agent_id, artid, article, dest_table, owner, cft_table, columns)
  15965.         values (@agent_id, @artid, @article, @dest_table, @owner, @cft_table, @columns)
  15966.  
  15967.     IF (@@ERROR != 0)
  15968.     begin
  15969.         raiserror('Debug:sp_addqueued_artinfo - insert failed', 16, 1)
  15970.         return (1)
  15971.     end
  15972.  
  15973.     --
  15974.     -- Do the queue initialization here
  15975.     -- this way we can initialize Snapshot/Logbased queued tran from one place
  15976.     --
  15977.     exec @retcode = dbo.sp_MSreset_queue @publisher, @publisher_db, @publication, @artid
  15978.     IF (@retcode != 0 or @@ERROR != 0)
  15979.     begin
  15980.         raiserror('Debug:sp_addqueued_artinfo - sp_MSreset_queue failed', 16, 1)
  15981.         return (1)
  15982.     end
  15983.     
  15984.     --
  15985.     -- all done
  15986.     --
  15987.     return 0    
  15988. END
  15989. go
  15990.  
  15991.  
  15992. raiserror('Creating procedure sp_addsynctriggers', 0,1)
  15993. go
  15994.  
  15995. CREATE PROCEDURE sp_addsynctriggers (
  15996.     @sub_table       sysname,            -- table name 
  15997.     @sub_table_owner sysname,            -- table owner
  15998.     @publisher      sysname,            -- publishing server name
  15999.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  16000.     @publication    sysname,            -- publication name.
  16001.     @ins_proc       sysname,
  16002.     @upd_proc       sysname,
  16003.     @del_proc       sysname,
  16004.     @cftproc        sysname,
  16005.     @proc_owner        sysname,
  16006.     @identity_col   sysname = 'NULL', 
  16007.     @ts_col         sysname = 'NULL',
  16008.     @filter_clause  nvarchar(4000) = 'NULL',
  16009.     @primary_key_bitmap  varbinary(4000),
  16010.     @identity_support bit = 0,
  16011.     @independent_agent bit = 0
  16012.     ,@distributor    sysname                -- distribution server name
  16013. )
  16014. AS
  16015. BEGIN
  16016.     set nocount on
  16017.  
  16018.     declare @db                        sysname
  16019.             ,@trigname                sysname
  16020.             ,@ins_trig                sysname
  16021.             ,@upd_trig                sysname
  16022.             ,@del_trig                sysname
  16023.             ,@qual_ins_trig            nvarchar(540)
  16024.             ,@qual_upd_trig            nvarchar(540)
  16025.             ,@qual_del_trig            nvarchar(540)
  16026.             ,@dbname                sysname
  16027.             ,@ccols                    int
  16028.             ,@cnt                    int
  16029.             ,@retcode                int
  16030.             ,@cmd                    nvarchar(4000)
  16031.             ,@merge_pub_object_bit    int
  16032.             ,@synctran_bit            int
  16033.             ,@object_id                int
  16034.             ,@bitmap_str                varchar(8000)
  16035.             ,@constraint_name            sysname
  16036.             ,@quoted_name            nvarchar(540)
  16037.             ,@qualname                nvarchar(540)
  16038.             ,@loctrancount             int
  16039.  
  16040.     select     @merge_pub_object_bit     = 128
  16041.             ,@synctran_bit            = 256
  16042.  
  16043.     --  Security Check
  16044.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  16045.     IF @@ERROR <> 0 or @retcode <> 0
  16046.     RETURN(1)
  16047.  
  16048.  
  16049.     -- Dist Agent executes this sproc with 'implicit transasctions on'.
  16050.     -- We take care of our own transactions boundaries to get out of tran 
  16051.     set implicit_transactions off
  16052.     select @loctrancount = @@trancount
  16053.     while @@trancount > 0 commit tran
  16054.  
  16055.     -- check valid server and database setting
  16056.     -- 1. nested trigger have to be on
  16057.     if exists (select * from master..sysconfigures where config = 115 and value = 0)
  16058.     begin
  16059.         raiserror(21081, 16, 1)
  16060.         return (1)
  16061.     end
  16062.  
  16063.     -- 2. db option: recursive trigger have to be off
  16064.     if DATABASEPROPERTY(db_name(), N'IsRecursiveTriggersEnabled') <> 0
  16065.     begin
  16066.         raiserror(21082, 16, 1)
  16067.         return (1)
  16068.     end    
  16069.     
  16070.     -- 2. db compatibility level have to be 7.0
  16071.     if exists (select * from master..sysdatabases where dbid = db_id() and 
  16072.         cmptlevel < 70)
  16073.     begin
  16074.         raiserror(21083, 16, 1)
  16075.         return (1)
  16076.     end    
  16077.     
  16078.     if lower(@sub_table_owner) = N'null'
  16079.         select @qualname = QUOTENAME(@sub_table)        
  16080.     else
  16081.         select @qualname = QUOTENAME(@sub_table_owner) + N'.' + QUOTENAME(@sub_table)
  16082.  
  16083.     -- Verify that table exists 
  16084.     select @object_id = object_id (@qualname)
  16085.     if @object_id is null
  16086.     begin
  16087.         raiserror(20507, 16, 1, @qualname, 'sp_addsynctriggers')
  16088.         return (1)
  16089.     end
  16090.  
  16091.     -- Add default to timestamp, identity and version guid column
  16092.     if OBJECTPROPERTY(@object_id, 'tablehastimestamp') <> 1
  16093.     begin
  16094.         select @constraint_name = 'MSrepl_synctran_ts_default_' + convert(nvarchar(10), @object_id)
  16095.         select @quoted_name = quotename(@ts_col)
  16096.         if @ts_col is not null and @ts_col not in ('null','NULL') and not exists
  16097.             (select * from sysobjects where name = @constraint_name)
  16098.         begin
  16099.             exec ('alter table ' + @qualname + 
  16100.                 ' add constraint ' + @constraint_name + 
  16101.                 ' default 0 for ' + @quoted_name )
  16102.             if @@ERROR<>0 return 1
  16103.         end
  16104.     end
  16105.     
  16106.     if OBJECTPROPERTY(@object_id, 'tablehasidentity') <> 1
  16107.     begin
  16108.         select @constraint_name = 'MSrepl_synctran_identity_default_' + convert(nvarchar(10), @object_id)
  16109.         select @quoted_name = quotename(@identity_col)
  16110.         if @identity_col is not null and @identity_col not in ('null','NULL') and not exists
  16111.             (select * from sysobjects where name = @constraint_name)
  16112.         begin
  16113.             exec ('alter table ' + @qualname + 
  16114.                 ' add constraint ' + @constraint_name + 
  16115.                 ' default 0 for ' + @quoted_name )
  16116.             if @@ERROR<>0 return 1
  16117.         end
  16118.     end
  16119.  
  16120.     -- The default constraint is transfered with snapshot already for native publication.
  16121.     -- Need to detect to see if default constraint already there.
  16122.     select @quoted_name = 'msrepl_tran_version'
  16123.     declare @colid int
  16124.     select @colid = colid from syscolumns where 
  16125.         id = @object_id and
  16126.         name = @quoted_name
  16127.     if not exists (select * from sysconstraints where
  16128.         id = @object_id and 
  16129.         colid = @colid and
  16130.         status & 5 = 5) -- default
  16131.     begin 
  16132.         select @constraint_name = 'MSrepl_tran_version_default_' + convert(nvarchar(10), @object_id)
  16133.         exec ('alter table ' + @qualname + 
  16134.             ' add constraint ' + @constraint_name + 
  16135.             ' default newid() for ' + @quoted_name )
  16136.         if @@ERROR<>0 return 1
  16137.     end
  16138.  
  16139.     -- If MSsubscription_properties table does not exists, create one.
  16140.     if (LOWER(@cftproc) = 'null')
  16141.     begin
  16142.         exec @retcode = dbo.sp_MScreate_sub_tables
  16143.             @tran_sub_table = 0,
  16144.             @property_table = 1,
  16145.             @sqlqueue_table = 0
  16146.     end
  16147.     else
  16148.     begin
  16149.         exec @retcode = dbo.sp_MScreate_sub_tables
  16150.             @tran_sub_table = 0,
  16151.             @property_table = 1,
  16152.             @sqlqueue_table = 1
  16153.     end
  16154.     IF @@ERROR <> 0 or @retcode <> 0
  16155.         RETURN(1)
  16156.  
  16157.     -- If no entry in MSsubscription_properties for this publication, add one.
  16158.     IF NOT EXISTS (select * from MSsubscription_properties 
  16159.             where UPPER(publisher) = UPPER(@publisher)
  16160.                 and publisher_db =  @publisher_db
  16161.                 and publication = @publication) 
  16162.     BEGIN
  16163.         -- Use status rpc for local publisher
  16164.         declare @security_mode int
  16165.         declare @login sysname
  16166.         if UPPER(@@servername) = UPPER(@publisher)
  16167.         begin
  16168.             select @security_mode = 2
  16169.         end
  16170.         else
  16171.         begin
  16172.             select @security_mode = 0
  16173.             select @login = 'sa'
  16174.         end
  16175.  
  16176.         exec @retcode = dbo.sp_link_publication
  16177.             @publisher = @publisher,
  16178.             @publisher_db = @publisher_db,
  16179.             @publication = @publication,
  16180.             @security_mode = @security_mode,
  16181.             @login = @login,
  16182.             @password = NULL,
  16183.             @distributor = @distributor
  16184.         IF @@ERROR <> 0 or @retcode <> 0
  16185.             RETURN(1)
  16186.     END
  16187.       
  16188.     if exists (select * from sysobjects where 
  16189.         replinfo & @merge_pub_object_bit <> 0 and
  16190.         id = @object_id)
  16191.     begin
  16192.         raiserror(21063, 16, 1, @qualname)
  16193.         return (1)
  16194.     end
  16195.     
  16196.     -- Get agent_id
  16197.     declare @agent_id int
  16198.  
  16199.     -- First try to get the agent id initialized by the distribution agent
  16200.     declare @login_time datetime
  16201.     select @login_time = login_time from master..sysprocesses where spid = @@spid
  16202.  
  16203.     select @agent_id = id from MSsubscription_agents where
  16204.         spid = @@spid and
  16205.         login_time = @login_time
  16206.  
  16207.     -- If row not found, the current call is not from a distribution agent. Uses
  16208.     -- are creating trigger manually using the script generated by
  16209.     -- sp_script_synctran_triggers.
  16210.     -- Get the row using the publication name. However, it is possible that there are
  16211.     -- more than one qualifed rows with different subscription_type, for example
  16212.     -- pull and push subscriptions to share agent publications or subscriptions that has
  16213.     -- not been cleaned up.
  16214.     if @agent_id is null
  16215.     begin
  16216.         declare @num_dup_rows int
  16217.         select @agent_id = avg(id), @num_dup_rows = count(*) from MSsubscription_agents where
  16218.             publisher = @publisher and
  16219.             publisher_db = @publisher_db and
  16220.             publication = case @independent_agent 
  16221.                 when 0 then N'ALL'
  16222.                 else @publication
  16223.                 end and
  16224.             -- We know the subscription must be updateble. This
  16225.             -- is to reduce the chance of dup rows.
  16226.             update_mode <> 0
  16227.  
  16228.         if @num_dup_rows > 1
  16229.         begin
  16230.             -- Raise subscription already exist error
  16231.             -- This should rarely happen.
  16232.             RAISERROR (14058, 16, -1)
  16233.             return(1)
  16234.         end
  16235.  
  16236.         if @agent_id is null
  16237.         begin
  16238.             raiserror(20588, 16, -1)
  16239.             return(1)
  16240.         end
  16241.     end
  16242.  
  16243.  
  16244.     /*
  16245.     **    Create system table MSreplication_objects if it does not exist
  16246.     */
  16247.     IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  16248.         type = 'U' AND name = 'MSreplication_objects')
  16249.         BEGIN
  16250.             CREATE TABLE dbo.MSreplication_objects
  16251.             (
  16252.             publisher sysname NULL,
  16253.             publisher_db sysname NULL,
  16254.                publication sysname NULL, 
  16255.             object_name    sysname NOT NULL,
  16256.             object_type    char(2) NOT NULL
  16257.             )
  16258.             IF @@ERROR <> 0
  16259.                 begin
  16260.                     rollback transaction 
  16261.                     return (1)
  16262.                 end
  16263.             
  16264.             CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  16265.             EXEC dbo.sp_MS_marksystemobject 'dbo.MSreplication_objects'
  16266.         END
  16267.  
  16268.  
  16269.     -- Drop all replication triggers on the source object
  16270.     -- We should drop all because we don't support updatable subscriptions to 
  16271.     -- multiple publications on same dest table.
  16272.     declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  16273.         select o.object_name, so.id from MSreplication_objects o, sysobjects so where
  16274.             o.object_name = so.name and
  16275.             so.parent_obj = @object_id and
  16276.             o.object_type = 'T'
  16277.  
  16278.     declare @old_id int 
  16279.     declare @old_name sysname
  16280.  
  16281.     OPEN object_cursor
  16282.     FETCH object_cursor INTO @old_name, @old_id
  16283.      WHILE (@@fetch_status <> -1)
  16284.     BEGIN
  16285.         -- Cleanup identity range table
  16286.         declare @parent_obj int
  16287.         select @parent_obj = 0
  16288.         select @parent_obj = parent_obj from sysobjects where id = @old_id
  16289.         if exists (select * from sysobjects where name = 'MSsub_identity_range')
  16290.             delete MSsub_identity_range where objid = @parent_obj
  16291.  
  16292.         -- Drop the trigger
  16293.         exec @retcode = dbo.sp_MSdrop_object 
  16294.             @object_id = @old_id
  16295.         if @retcode <> 0 or @@error <> 0
  16296.             goto UNDO
  16297.         delete from MSreplication_objects where object_name=@old_name
  16298.         FETCH object_cursor INTO @old_name, @old_id
  16299.     END
  16300.     CLOSE object_cursor
  16301.     DEALLOCATE object_cursor
  16302.  
  16303.     -- Generate trigger names
  16304.         select @trigname = RTRIM(SUBSTRING(@sub_table,1,110))
  16305.     select @ins_trig = N'trg_MSsync_ins_' + @trigname 
  16306.     select @upd_trig = N'trg_MSsync_upd_' + @trigname 
  16307.     select @del_trig = N'trg_MSsync_del_' + @trigname 
  16308.  
  16309.     -- check uniqueness of names and revert to ugly guid-based name if friendly name already exists
  16310.     if exists (select name from sysobjects where name in (@ins_trig, @upd_trig, @del_trig))
  16311.         begin
  16312.             declare @guid_name nvarchar(36)
  16313.             select @guid_name =  convert (nvarchar(36), newid())
  16314.         select @ins_trig = 'trg_MSsync_ins_' + @guid_name
  16315.         select @upd_trig = 'trg_MSsync_upd_' + @guid_name
  16316.         select @del_trig = 'trg_MSsync_del_' + @guid_name
  16317.         end
  16318.  
  16319.     -- Get qual names
  16320.     if lower(@sub_table_owner) = N'null'
  16321.     begin
  16322.         select @qual_ins_trig = @ins_trig
  16323.         select @qual_upd_trig = @upd_trig
  16324.         select @qual_del_trig = @del_trig
  16325.     end
  16326.     else
  16327.     begin
  16328.         select @qual_ins_trig = QUOTENAME(@sub_table_owner) + N'.' + @ins_trig
  16329.         select @qual_upd_trig = QUOTENAME(@sub_table_owner) + N'.' + @upd_trig
  16330.         select @qual_del_trig = QUOTENAME(@sub_table_owner) + N'.' + @del_trig
  16331.     end
  16332.  
  16333.  
  16334.     exec @retcode = master..xp_varbintohexstr @primary_key_bitmap, @bitmap_str output
  16335.     if @retcode <> 0 or @@error <> 0
  16336.         return 1
  16337.  
  16338.  
  16339.  
  16340. /*
  16341.     exec ('if exists (select * from sysobjects where name = N''' + @ins_trig + N''' and xtype = N''TR'')
  16342.         drop trigger ' + @ins_trig)
  16343.     exec ('if exists (select * from sysobjects where name = N''' + @upd_trig + N''' and xtype = N''TR'')
  16344.         drop trigger ' + @upd_trig)
  16345.     exec ('if exists (select * from sysobjects where name = N''' + @del_trig + N''' and xtype = N''TR'')
  16346.         drop trigger ' + @del_trig)
  16347.  
  16348. */
  16349.     -- We are now going to create triggers, so start a transaction
  16350.     begin tran
  16351.         -- Call out to individual create trigger routines
  16352.         select @dbname = db_name()
  16353.         select @cmd = 'sp_MSscript_sync_ins_trig ' + 
  16354.             convert( nvarchar, @object_id )  + ', N' + 
  16355.             quotename(@publisher, '''')     + ', N' + 
  16356.             quotename(@publisher_db, '''')  + ', N' + 
  16357.             quotename(@publication, '''')   + ', N' + 
  16358.             quotename(@ins_trig, '''')      + ', N' + 
  16359.             quotename(@ins_proc, '''')      + ', N' + 
  16360.             quotename(@proc_owner, '''')    + ', N' + 
  16361.             quotename(@cftproc, '''')       + ', ' + 
  16362.             convert(nvarchar(10), @agent_id) + ', N' + 
  16363.             quotename(@identity_col, '''') + ', N' + 
  16364.             quotename(@ts_col, '''')        
  16365.         if @filter_clause in ('NULL', 'null')
  16366.             select @cmd = @cmd + ', null' 
  16367.         else 
  16368.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  16369.                                     
  16370.         -- Set primary key bitmap
  16371.         select @cmd = @cmd + ', ' + @bitmap_str
  16372.  
  16373.         exec @retcode = master..xp_execresultset @cmd, @dbname
  16374.         IF @@ERROR <> 0 or @retcode <> 0
  16375.             goto UNDO
  16376.         select @cmd = 'sp_MSscript_sync_upd_trig ' + 
  16377.             convert( nvarchar, @object_id )  + ', N' + 
  16378.             quotename(@publisher, '''')     + ', N' + 
  16379.             quotename(@publisher_db, '''')  + ', N' + 
  16380.             quotename(@publication, '''')   + ', N' + 
  16381.             quotename(@upd_trig, '''')      + ', N' + 
  16382.             quotename(@upd_proc, '''')      + ', N' + 
  16383.             quotename(@proc_owner, '''')    + ', N' + 
  16384.             quotename(@cftproc, '''')       + ', ' + 
  16385.             convert(nvarchar(10), @agent_id)  + ', N' + 
  16386.             quotename(@identity_col, '''')  + ', N' + 
  16387.             quotename(@ts_col, '''')        
  16388.         if @filter_clause in ('NULL', 'null')
  16389.             select @cmd = @cmd + ', null' 
  16390.         else 
  16391.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''
  16392.                                     
  16393.         -- Set primary key bitmap
  16394.         select @cmd = @cmd + ', ' + @bitmap_str
  16395.  
  16396.         exec @retcode = master..xp_execresultset @cmd, @dbname
  16397.         IF @@ERROR <> 0 or @retcode <> 0
  16398.             goto UNDO
  16399.  
  16400.         select @cmd = 'sp_MSscript_sync_del_trig ' + 
  16401.             convert( nvarchar, @object_id )  + ', N' + 
  16402.             quotename(@publisher, '''')     + ', N' + 
  16403.             quotename(@publisher_db, '''')  + ', N' + 
  16404.             quotename(@publication, '''')   + ', N' + 
  16405.             quotename(@del_trig, '''')      + ', N' + 
  16406.             quotename(@del_proc, '''')      + ', N' + 
  16407.             quotename(@proc_owner, '''')    + ', N' + 
  16408.             quotename(@cftproc, '''')       + ', ' + 
  16409.             convert(nvarchar(10), @agent_id) + ', N' + 
  16410.             quotename(@identity_col, '''')  + ', N' + 
  16411.             quotename(@ts_col, '''')        
  16412.         if @filter_clause in ('NULL', 'null')
  16413.             select @cmd = @cmd + ', null' 
  16414.         else 
  16415.             select @cmd = @cmd + ', N''' + replace (@filter_clause,'''','''''')  + ''''            
  16416.  
  16417.         -- Set primary key bitmap
  16418.         select @cmd = @cmd + ', ' + @bitmap_str
  16419.  
  16420.         exec @retcode = master..xp_execresultset @cmd, @dbname
  16421.         IF @@ERROR <> 0 or @retcode <> 0
  16422.             goto UNDO
  16423.  
  16424.         -- Drop old entries before insert. The triggers with those names
  16425.         -- are created as above.
  16426.         delete MSreplication_objects where object_name = @ins_trig
  16427.         IF @@ERROR <> 0
  16428.             goto UNDO
  16429.         delete MSreplication_objects where object_name = @upd_trig
  16430.         IF @@ERROR <> 0
  16431.             goto UNDO
  16432.         delete MSreplication_objects where object_name = @del_trig
  16433.         IF @@ERROR <> 0
  16434.             goto UNDO
  16435.  
  16436.         -- Mark procedures as system procs so they don't show up in the UI
  16437.         exec dbo.sp_MS_marksystemobject @qual_ins_trig
  16438.         IF @@ERROR <> 0
  16439.             goto UNDO
  16440.  
  16441.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  16442.                     values(@publisher, @publisher_db, @publication, @ins_trig, 'T')
  16443.         IF @@ERROR <> 0
  16444.             goto UNDO
  16445.  
  16446.         exec dbo.sp_MS_marksystemobject @qual_upd_trig
  16447.         IF @@ERROR <> 0
  16448.             goto UNDO
  16449.                 
  16450.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  16451.                     values(@publisher, @publisher_db, @publication, @upd_trig, 'T')
  16452.         IF @@ERROR <> 0
  16453.             goto UNDO
  16454.  
  16455.         exec dbo.sp_MS_marksystemobject @qual_del_trig
  16456.         IF @@ERROR <> 0
  16457.             goto UNDO
  16458.  
  16459.         insert into MSreplication_objects(publisher, publisher_db, publication, object_name, object_type)
  16460.                     values(@publisher, @publisher_db, @publication, @del_trig, 'T')
  16461.         IF @@ERROR <> 0
  16462.             goto UNDO
  16463.  
  16464.         -- Mark the table for warnings in BCP
  16465.         update sysobjects set replinfo = replinfo | @synctran_bit where
  16466.             id = @object_id
  16467.         IF @@ERROR <> 0
  16468.             goto UNDO
  16469.  
  16470.         -- Set up identity range table
  16471.         if @identity_support <> 0
  16472.         begin
  16473.             if not exists (select * from sysobjects where name = 'MSsub_identity_range')
  16474.             begin
  16475.                 create table dbo.MSsub_identity_range (
  16476.                     objid int not null,
  16477.                     range bigint not null,
  16478.                     last_seed bigint not null,
  16479.                     threshold int not null)
  16480.                 IF @@ERROR <> 0
  16481.                     goto UNDO
  16482.             
  16483.                 CREATE UNIQUE CLUSTERED INDEX ucMSsub_identity_range ON dbo.MSsub_identity_range (objid)
  16484.                 
  16485.                 EXEC dbo.sp_MS_marksystemobject 'MSsub_identity_range'
  16486.                 IF @@ERROR <> 0
  16487.                     goto UNDO
  16488.             end
  16489.             if not exists (select * from MSsub_identity_range where objid = @object_id)
  16490.             begin
  16491.                 -- add zero at the beginning.
  16492.                 insert into MSsub_identity_range (objid, range, last_seed, threshold) values
  16493.                     (@object_id, 0, 0, 0)
  16494.                 IF @@ERROR <> 0
  16495.                     goto UNDO
  16496.             end
  16497.         end
  16498.  
  16499.     -- commit tran
  16500.     commit tran
  16501.  
  16502.     -- Set trigger firing order for insert
  16503.     exec dbo.sp_settriggerorder @qual_ins_trig,'first','insert'
  16504.     exec dbo.sp_settriggerorder @qual_upd_trig,'first','update'
  16505.     exec dbo.sp_settriggerorder @qual_del_trig,'first','delete'
  16506.     
  16507.     -- Ignore errors.
  16508.     exec dbo.sp_MSsub_cleanup_orphans
  16509.  
  16510.     -- restore the trancount if necessary
  16511.     if (@loctrancount > 0)
  16512.     begin
  16513.         while (@@trancount < @loctrancount)
  16514.             begin tran
  16515.     end
  16516.  
  16517.     return (0)
  16518. UNDO:
  16519.     if @@trancount <> 0
  16520.         rollback tran
  16521.     return(1)
  16522. END
  16523. go
  16524.  
  16525. raiserror('Creating procedure sp_setreplfailovermode', 0,1)
  16526. go
  16527.  
  16528. create procedure sp_setreplfailovermode (
  16529.     @publisher sysname,
  16530.     @publisher_db sysname,
  16531.     @publication sysname,
  16532.     @failover_mode nvarchar (10), 
  16533.     @override tinyint = 0)
  16534. as
  16535. begin
  16536.     set nocount on
  16537.     declare    @failover_mode_id tinyint, 
  16538.             @current_failover_mode_id bit,
  16539.             @retcode int,
  16540.             @queue_id sysname,
  16541.             @fqueue_empty int,
  16542.             @update_mode int,
  16543.             @queue_server sysname
  16544.  
  16545.     if @failover_mode not in (N'immediate', N'sync', N'queued')
  16546.     begin
  16547.         raiserror (21184, 16, 1, '@failover_mode', 'immediate', 'sync', 'queued')
  16548.         return 1            
  16549.     end
  16550.     else
  16551.     begin
  16552.         if @failover_mode = 'immediate' or @failover_mode = 'sync'
  16553.             select @failover_mode_id = 0
  16554.         else if @failover_mode = 'queued'
  16555.             select @failover_mode_id = 1
  16556.     end
  16557.  
  16558.     --
  16559.     -- Only valid to get/set failover_mode, 
  16560.     -- if update_mode is failover (3,5)
  16561.     --
  16562.     select    @queue_id = queue_id, 
  16563.             @queue_server = queue_server,
  16564.             @current_failover_mode_id = failover_mode,
  16565.             @update_mode = update_mode
  16566.     from MSsubscription_agents
  16567.     where UPPER(publisher) = UPPER(@publisher) and 
  16568.         publisher_db = @publisher_db and
  16569.         publication = @publication and
  16570.         update_mode in (3,5)
  16571.  
  16572.     -- no such row exists
  16573.     if (@current_failover_mode_id is NULL)        
  16574.     begin
  16575.         raiserror (21185, 16, 1)
  16576.         return 1
  16577.     end
  16578.  
  16579.     -- should have a queue entry
  16580.     if (@queue_id is NULL)
  16581.     begin
  16582.         raiserror(21186, 16, 1, @publisher)
  16583.         return 1
  16584.     end
  16585.  
  16586.     --
  16587.     -- do the transition
  16588.     --
  16589.     if ((@current_failover_mode_id = 0 and @failover_mode_id = 0) or
  16590.             (@current_failover_mode_id = 1 and @failover_mode_id = 1))
  16591.     begin
  16592.         --
  16593.         -- Going from immediate to immediate, queued to queued is no-op
  16594.         --
  16595.         raiserror (21187, 16, 1)
  16596.     end
  16597.     else if (@current_failover_mode_id = 0 and @failover_mode_id = 1)
  16598.     begin
  16599.         --
  16600.         -- Going from immediate to queued : update MSsubscription_agents
  16601.         --
  16602.         update MSsubscription_agents
  16603.             set failover_mode = @failover_mode_id
  16604.             where UPPER(publisher) = UPPER(@publisher) and 
  16605.                 publisher_db = @publisher_db and
  16606.                 publication = @publication and
  16607.                 update_mode in (3,5)
  16608.  
  16609.         raiserror (21188, 10, 1, 'immediate', 'queued')
  16610.     end
  16611.     else if (@current_failover_mode_id = 1 and @failover_mode_id = 0)
  16612.     begin
  16613.         --
  16614.         -- Going from queued to immediate : if override is not set
  16615.         -- then check if the queue is empty and then allow if empty.
  16616.         -- If override is set, just update MSsubscription_agents
  16617.         --
  16618.         if (@override = 0)
  16619.         begin
  16620.             if (@update_mode = 3)
  16621.             begin
  16622.                 --
  16623.                 -- MSMQ processing
  16624.                 -- prefix the queue_id with queue server in direct format
  16625.                 -- and then perform peek in the queue
  16626.                 --
  16627.                 select @queue_id = N'DIRECT=OS:' + @queue_server + N'\PRIVATE$\' + @queue_id
  16628.                 
  16629.                 exec @retcode = master.dbo.xp_peekqueue @queue_id, @fqueue_empty output, 0
  16630.                 if (@@error != 0 or @retcode != 0)
  16631.                 begin
  16632.                     raiserror('sp_setreplfailovermode(debug): xp_peekqueue execution failed', 16, 1)
  16633.                     return 1
  16634.                 end
  16635.  
  16636.                 if (@fqueue_empty != 1)
  16637.                 begin
  16638.                     raiserror(21189, 16, 1, @queue_id)
  16639.                     return 1
  16640.                 end
  16641.             end
  16642.             else
  16643.             begin
  16644.                 --
  16645.                 -- SQL Queue processing
  16646.                 --
  16647.                 if exists (select * from MSreplication_queue 
  16648.                     where UPPER(publisher) = UPPER(@publisher) and 
  16649.                             publisher_db = @publisher_db and
  16650.                             publication = @publication )
  16651.                 begin
  16652.                     raiserror(21189, 16, 2, @queue_id)
  16653.                     return 1
  16654.                 end
  16655.             end
  16656.         end
  16657.         else
  16658.         begin
  16659.             raiserror(21190, 10, 1, 'queued', 'immediate')
  16660.         end
  16661.  
  16662.         --
  16663.         -- update MSsubscription_agents
  16664.         --
  16665.         update MSsubscription_agents
  16666.             set failover_mode = @failover_mode_id
  16667.             where publisher = @publisher and 
  16668.                 publisher_db = @publisher_db and
  16669.                 publication = @publication and
  16670.                 update_mode in (3,5)
  16671.  
  16672.         raiserror (21188, 10, 1, 'queued', 'immediate')
  16673.     end
  16674.  
  16675.     -- All done
  16676.     return 0
  16677. end
  16678. go
  16679.  
  16680. exec dbo.sp_MS_marksystemobject sp_setreplfailovermode
  16681. go
  16682.  
  16683. raiserror('Creating procedure sp_helpreplfailovermode', 0,1)
  16684. go
  16685.  
  16686. create procedure sp_helpreplfailovermode (
  16687.     @publisher sysname,
  16688.     @publisher_db sysname,
  16689.     @publication sysname,
  16690.     @failover_mode_id tinyint = 0 output,
  16691.     @failover_mode nvarchar(10) = NULL output)
  16692. as
  16693. BEGIN
  16694.     declare    @subfound bit
  16695.     
  16696.     --
  16697.     -- Check if the table MSsubscription_agents exists
  16698.     --
  16699.     if exists (select * from dbo.sysobjects 
  16700.                     where name = 'MSsubscription_agents')
  16701.     begin
  16702.         --
  16703.         -- Only valid to get failover_mode, if failover_mode is failover (3,5)
  16704.         --
  16705.         if exists (select * from dbo.MSsubscription_agents
  16706.                 where publisher = @publisher and 
  16707.                     publisher_db = @publisher_db and
  16708.                     publication = @publication and
  16709.                     update_mode in (3,5) )
  16710.             select @subfound = 1
  16711.         else
  16712.             select @subfound = 0
  16713.     end
  16714.     else
  16715.         select @subfound = 0
  16716.     
  16717.     --
  16718.     -- Did we find an entry for initialized failover subscription
  16719.     --
  16720.     if (@subfound = 0)
  16721.     begin
  16722.         --
  16723.         -- Three possibilities : uninitialized subscription, non existent subscription
  16724.         -- or a non-mixed mode. Check If we have a PULL uninitialized subscription
  16725.         --
  16726.         if exists (select * from dbo.sysobjects 
  16727.                         where name = 'MSreplication_subscriptions')
  16728.         begin
  16729.             if exists (select * from dbo.MSreplication_subscriptions
  16730.                             where publisher = @publisher and 
  16731.                                 publisher_db = @publisher_db and
  16732.                                 publication = @publication and
  16733.                                 update_mode in (3,5) )
  16734.             begin
  16735.                 --
  16736.                 -- unitialized PULL subscription : return the default values
  16737.                 --
  16738.                 select @failover_mode_id = 0
  16739.                 select @subfound = 1
  16740.             end
  16741.         end
  16742.  
  16743.         if (@subfound = 0)
  16744.         begin
  16745.             raiserror ('sp_helpreplfailovermode: Subscription for [%s].[%s].[%s] either has not been initialized or does not exist or does not support mixed mode',
  16746.                         16, 1, @publisher, @publisher_db, @publication)
  16747.             return 1
  16748.         end
  16749.     end
  16750.     else
  16751.     begin
  16752.         --
  16753.         -- we found our subscription
  16754.         --
  16755.         select @failover_mode_id = failover_mode
  16756.         from dbo.MSsubscription_agents
  16757.         where publisher = @publisher and 
  16758.             publisher_db = @publisher_db and
  16759.             publication = @publication and
  16760.             update_mode in (3,5) 
  16761.             
  16762.         --
  16763.         -- initialize to 'immediate' if necessary
  16764.         --
  16765.         if @failover_mode_id not in (0, 1)
  16766.         begin
  16767.             raiserror ('sp_helpreplfailovermode: invalid failover_mode value %d for [%s].[%s].[%s], setting to 0 [immediate]', 
  16768.                 11, 1, @failover_mode_id, @publisher, @publisher_db, @publication)
  16769.             update dbo.MSsubscription_agents 
  16770.             set failover_mode = 0
  16771.             where publisher = @publisher and 
  16772.                 publisher_db = @publisher_db and
  16773.                 publication = @publication and
  16774.                 update_mode in (3,5) 
  16775.  
  16776.             select @failover_mode_id = 0
  16777.         end
  16778.     end
  16779.  
  16780.     --
  16781.     -- prepare the output
  16782.     --
  16783.     select @failover_mode = case 
  16784.         when @failover_mode_id = 0 then N'immediate'
  16785.         when @failover_mode_id = 1 then N'queued'
  16786.         end
  16787.         
  16788.     select N'failover_mode value'  = @failover_mode_id, 
  16789.             N'failover_mode' = @failover_mode
  16790.  
  16791.     --
  16792.     -- all done
  16793.     --
  16794.     return 0
  16795. END
  16796. go
  16797. exec dbo.sp_MS_marksystemobject sp_helpreplfailovermode
  16798. go
  16799.  
  16800. raiserror('Creating procedure sp_helpreplicationdboption', 0,1)
  16801. go
  16802.  
  16803. CREATE PROCEDURE sp_helpreplicationdboption (
  16804.     @dbname sysname = '%', @type sysname = 'replication allowed'
  16805. )
  16806. AS
  16807. BEGIN
  16808.     SET NOCOUNT ON
  16809.  
  16810.     /*
  16811.     ** Declarations.
  16812.     */
  16813.  
  16814.     DECLARE @retcode int
  16815.             ,@typebit int
  16816.             ,@distbit int -- bit to distinguish distribution databases
  16817.             ,@dbowner bit
  16818.             ,@dbreadonly bit
  16819.             ,@replication_db sysname
  16820.  
  16821.     SELECT @distbit = 16
  16822.             ,@dbowner = 0
  16823.             ,@dbreadonly = 0
  16824.  
  16825.     -- don't do security check.
  16826.  
  16827.     if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'publish%')
  16828.         select @typebit = 1
  16829.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'subscribe%')
  16830.         select @typebit = 2
  16831.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'merge publish%')
  16832.         select @typebit = 4
  16833.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'merge subscribe%')
  16834.         select @typebit = 8
  16835.     else if (lower(@type collate SQL_Latin1_General_CP1_CS_AS) like 'replication allowed%')
  16836.         select @typebit = 0
  16837.     else        
  16838.     begin
  16839.         raiserror(14091,-1,-1)
  16840.         return 1
  16841.     end
  16842.  
  16843.     /*
  16844.     ** Parameter Check:  @dbname.
  16845.     ** Check to make sure that the database name conforms to the rules
  16846.     ** for identifiers.
  16847.     */
  16848.  
  16849.     IF @dbname <> '%'
  16850.     BEGIN
  16851.         EXECUTE @retcode = dbo.sp_validname @dbname
  16852.         IF @@ERROR <> 0 OR @retcode <> 0
  16853.         RETURN (1)
  16854.     END
  16855.  
  16856.     /*
  16857.     ** Show databases with this option enabled.
  16858.     */
  16859.     CREATE TABLE #replicationdbs (name sysname collate database_default not null, id int identity NOT NULL, transpublish bit not null, mergepublish bit not null, dbowner bit not null, dbreadonly bit not null)
  16860.     if @typebit <> 0
  16861.     begin
  16862.         INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner, dbreadonly)
  16863.             SELECT name, 
  16864.                 case when (category & 1) <> 0 then 1 else 0 end,
  16865.                 case when (category & 4) <> 0 then 1 else 0 end,
  16866.                 @dbowner,
  16867.                 DATABASEPROPERTY(name, N'IsReadOnly')
  16868.             FROM master.dbo.sysdatabases
  16869.             WHERE ((@dbname = N'%') OR (name = @dbname collate database_default))
  16870.                 AND (category & @typebit) <> 0 
  16871.                 AND (HAS_DBACCESS ( name ) = 1)
  16872.  
  16873.         DECLARE hCdboinfo CURSOR LOCAL FAST_FORWARD FOR
  16874.             SELECT name FROM #replicationdbs
  16875.             FOR READ ONLY
  16876.         OPEN hCdboinfo
  16877.         FETCH hCdboinfo INTO @replication_db
  16878.         WHILE (@@fetch_status <> -1)
  16879.         BEGIN
  16880.             EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  16881.             IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  16882.             BEGIN
  16883.                 UPDATE #replicationdbs set dbowner = 1 where name = @replication_db
  16884.             END
  16885.             FETCH hCdboinfo INTO @replication_db
  16886.         END
  16887.         CLOSE hCdboinfo
  16888.         DEALLOCATE hCdboinfo
  16889.     end            
  16890.     else
  16891.     begin
  16892.         DECLARE @db_category int
  16893.  
  16894.         /* Filter out distribution databases */
  16895.         DECLARE hC  CURSOR LOCAL FAST_FORWARD FOR 
  16896.             SELECT name, category, DATABASEPROPERTY(name, N'IsReadOnly')
  16897.             FROM master.dbo.sysdatabases 
  16898.             WHERE ((@dbname = N'%') OR (name = @dbname collate database_default)) 
  16899.                 AND (category & @distbit) = 0 
  16900.                 AND (HAS_DBACCESS ( name ) = 1)
  16901.             FOR READ ONLY
  16902.         OPEN hC
  16903.         FETCH hC INTO @replication_db, @db_category, @dbreadonly
  16904.         WHILE (@@fetch_status <> -1)
  16905.         BEGIN
  16906.             if @replication_db NOT IN ('master','model','tempdb','msdb','MSSQLWeb')
  16907.             BEGIN
  16908.                 EXEC @retcode = sp_MSrepl_isdbowner @replication_db
  16909.                 IF (@retcode IS NOT NULL) AND (@retcode <> 0)
  16910.                 BEGIN
  16911.                     SELECT @dbowner = 1
  16912.                 END
  16913.                 ELSE
  16914.                 BEGIN
  16915.                     SELECT @dbowner = 0
  16916.                 END
  16917.                 INSERT INTO #replicationdbs (name, transpublish, mergepublish, dbowner, dbreadonly) 
  16918.                 VALUES (@replication_db,
  16919.                         case when (@db_category & 1) <> 0 then 1 else 0 end,
  16920.                         case when (@db_category & 4) <> 0 then 1 else 0 end,
  16921.                         @dbowner, @dbreadonly)
  16922.             END
  16923.             FETCH hC INTO @replication_db, @db_category, @dbreadonly
  16924.         END
  16925.         CLOSE hC
  16926.         DEALLOCATE hC
  16927.     end
  16928.     SELECT * FROM #replicationdbs
  16929.     -- DROP TABLE #replicationdbs
  16930. END
  16931. go
  16932.  
  16933. raiserror('Creating procedure sp_MScheck_agent_instance', 0,1)
  16934. GO
  16935. CREATE PROCEDURE sp_MScheck_agent_instance
  16936. @application_name sysname,
  16937. @agent_type int = NULL
  16938.  
  16939. as
  16940.     declare @count_pro int
  16941.     set nocount on
  16942.     select @count_pro = count(*) from master..sysprocesses where 
  16943.         program_name = @application_name collate database_default
  16944.     -- type 3 is for 7.0 distribution agent backward compatibility.
  16945.     if @agent_type = 3
  16946.     begin
  16947.         -- The distribution agent will before connecting to the publisher with unique 
  16948.         -- application name
  16949.         if @count_pro > 0
  16950.             raiserror (21036, 16, -1, 'distribution')
  16951.     end
  16952.     -- 10 is 7.5 version of the distribution agent.
  16953.     else if @agent_type = 10
  16954.     begin
  16955.         -- The distribution agent will connecting to the publisher with unique 
  16956.         -- application name and then check.
  16957.         if @count_pro > 1
  16958.             raiserror (21036, 16, -1, 'distribution')
  16959.     end
  16960.     else if @agent_type = 4
  16961.     begin
  16962.         -- The merge agent will connect to the publisher with unique application name
  16963.         -- then call this procedure
  16964.         if @count_pro > 1 
  16965.             raiserror (21036, 16, -1, 'merge')
  16966.     end
  16967.     else if @agent_type = 1
  16968.     begin
  16969.         -- The snapshot agent will connect to the distributiondb with unique application name
  16970.         -- then call this procedure
  16971.         if @count_pro > 2 
  16972.             raiserror (21036, 16, -1, 'snapshot')
  16973.     end
  16974.     else if @agent_type = 2
  16975.     begin
  16976.         -- The logreader agent will connect to the distributiondb with unique application name
  16977.         -- then call this procedure
  16978.         if @count_pro > 1 
  16979.             raiserror (21036, 16, -1, 'logreader')
  16980.     end
  16981.     else if @agent_type = 9
  16982.     begin
  16983.         -- The queuereader agent will connect to the distributiondb with unique application name
  16984.         -- then call this procedure
  16985.         if @count_pro > 1 
  16986.             raiserror (21036, 16, -1, 'queuereader')
  16987.     end
  16988. go
  16989.  
  16990. CREATE PROCEDURE sp_MSBumpupCompLevel(
  16991. @pubid                uniqueidentifier,
  16992. @new_level            int
  16993. )
  16994. as
  16995.  
  16996. declare @retcode int
  16997. /*
  16998. ** Security Check
  16999. */
  17000.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  17001.     IF @@ERROR <> 0 or @retcode <> 0
  17002.         return (1)
  17003.  
  17004.     /* always bump UP, not Down in any case */
  17005.     update sysmergepublications set backward_comp_level = @new_level where pubid=@pubid and backward_comp_level < @new_level
  17006.     if @@ERROR<>0
  17007.         return (1)
  17008.     return (0)
  17009. GO
  17010. exec dbo.sp_MS_marksystemobject sp_MSBumpupCompLevel
  17011. go
  17012.  
  17013. grant execute on dbo.sp_MSBumpupCompLevel to public
  17014. go
  17015.  
  17016.  
  17017. CREATE PROCEDURE sp_MSCleanupForPullReinit (
  17018.     @publication         sysname,
  17019.     @publisher_db        sysname,
  17020.     @publisher             sysname = @@servername
  17021.     ) AS
  17022.     declare @pubid         uniqueidentifier
  17023.     declare @artid         uniqueidentifier
  17024.     declare @retcode    smallint
  17025.  
  17026.     /*
  17027.     ** Security Check
  17028.     */
  17029.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  17030.     IF @@ERROR <> 0 or @retcode <> 0
  17031.         return (1)
  17032.  
  17033.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  17034.     select @pubid = pubid FROM sysmergepublications 
  17035.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  17036.  
  17037.     /* Normal case - nothing to cleanup, just return */
  17038.     if @pubid is null
  17039.         return (1)    
  17040.  
  17041.     begin transaction
  17042.     save tran cleanupforreinit
  17043.     /* 
  17044.     ** Make sure you NULL out gen_cur for other articles that share this table 
  17045.     ** since we are deleting the genhistroy row for that generation 
  17046.     */
  17047.     update sysmergearticles set gen_cur=NULL where gen_cur in
  17048.         (select generation from MSmerge_genhistory where pubid = @pubid)
  17049.     if @@ERROR<>0 
  17050.         goto Error
  17051.     delete from MSmerge_genhistory where pubid = @pubid
  17052.     if @@ERROR<>0 
  17053.         goto Error
  17054.     delete from sysmergesubsetfilters where pubid=@pubid
  17055.     if @@ERROR<>0 
  17056.         goto Error
  17057.     delete from sysmergeschemachange where pubid = @pubid
  17058.     if @@ERROR<>0 
  17059.         goto Error
  17060.     delete from MSmerge_contents where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  17061.     if @@ERROR<>0 
  17062.         goto Error
  17063.     delete from MSmerge_tombstone where tablenick in (select nickname from sysmergearticles where pubid=@pubid)
  17064.     if @@ERROR<>0 
  17065.         goto Error
  17066.     update MSmerge_replinfo set recgen = NULL, recguid = NULL, sentgen = NULL, sentguid = NULL 
  17067.             where repid in ( select subid from sysmergesubscriptions where pubid = @pubid)
  17068.     if @@ERROR<>0 
  17069.         goto Error
  17070.  
  17071.     commit tran 
  17072.     return (0)
  17073.  
  17074. Error:
  17075.     rollback tran cleanupforreinit
  17076.     commit tran 
  17077.     return (1)
  17078. GO
  17079. exec dbo.sp_MS_marksystemobject sp_MSCleanupForPullReinit
  17080. go
  17081.  
  17082. grant execute on dbo.sp_MSCleanupForPullReinit to public
  17083. go
  17084.  
  17085.  
  17086. raiserror('Creating procedure sp_MSpublicationcleanup', 0,1)
  17087. GO
  17088.  
  17089. CREATE PROCEDURE sp_MSpublicationcleanup (
  17090.     @publication         sysname,
  17091.     @publisher_db        sysname,
  17092.     @publisher               sysname = @@servername
  17093.     ) AS
  17094.     declare @pubid         uniqueidentifier
  17095.     declare @artid         uniqueidentifier
  17096.     declare @retcode    smallint
  17097.     declare @objectname sysname
  17098.     declare @objectowner sysname
  17099.  
  17100.     /*
  17101.     ** Security Check
  17102.     */
  17103.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  17104.     IF @@ERROR <> 0 or @retcode <> 0
  17105.         return (1)
  17106.  
  17107.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  17108.     select @pubid = pubid FROM sysmergepublications 
  17109.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db = @publisher_db
  17110.  
  17111.     /* Normal case - nothing to cleanup, just return */
  17112.     if @pubid is null
  17113.         return (1)
  17114.  
  17115.     /* 
  17116.     ** If we are deleting the last publication in the database, ie there are articles in
  17117.     ** sysmergearticles with a different pubid then the one being dropped
  17118.     ** then remove all the rows in MSmerge_genhistory, MSmerge_contents and MSmerge_tombstone 
  17119.     ** use a truncate table in order to make the operation non logged and hence efficient
  17120.     */
  17121.     if not exists (select * from sysmergearticles where pubid <> @pubid)
  17122.         begin
  17123.             truncate table MSmerge_genhistory
  17124.             truncate table MSmerge_contents
  17125.             truncate table MSmerge_tombstone
  17126.         end
  17127.  
  17128.     begin transaction
  17129.     save tran MSpublicationcleanup
  17130.     /* Clean up the articles for this publication, and delete the row */
  17131.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17132.     while @artid is not null
  17133.         begin
  17134.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  17135.             begin
  17136.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  17137.                 if @retcode<>0 or @@ERROR<>0 
  17138.                     goto Error
  17139.             end
  17140.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  17141.         if @@ERROR<>0 
  17142.             goto Error
  17143.         set @artid = NULL
  17144.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17145.         end
  17146.         
  17147.     /* Unmark all schema articles in this publication */
  17148.     if exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  17149.     begin
  17150.         declare hschemaarticle_cur cursor local fast_forward for
  17151.             select destination_object, destination_owner from sysmergeschemaarticles where
  17152.             pubid = @pubid 
  17153.         for read only
  17154.         open hschemaarticle_cur
  17155.         fetch hschemaarticle_cur into @objectname, @objectowner
  17156.         while (@@fetch_status<>-1)
  17157.         begin
  17158.                 exec  sp_MSunmarkschemaobject @objectname, @objectowner    
  17159.                 if @retcode<>0 or @@ERROR<>0 
  17160.                     goto Error
  17161.                 fetch hschemaarticle_cur into @objectname, @objectowner
  17162.         end
  17163.         close hschemaarticle_cur
  17164.         deallocate hschemaarticle_cur
  17165.  
  17166.         /* Delete all schema article rows for this publication*/
  17167.         delete from sysmergeschemaarticles where pubid = @pubid
  17168.         if @@ERROR<>0 
  17169.             goto Error
  17170.     end
  17171.     
  17172.     /* Now clean up any traces in other system tables */
  17173.  
  17174.     /* 
  17175.     ** Make sure you NULL out gen_cur for other articles that share this table 
  17176.     ** since we are deleting the genhistroy row for that generation 
  17177.     */
  17178.     update sysmergearticles set gen_cur=NULL where gen_cur in
  17179.         (select generation from MSmerge_genhistory where pubid = @pubid)
  17180.     if @@ERROR<>0 
  17181.         goto Error
  17182.     delete from MSmerge_genhistory where pubid = @pubid
  17183.     if @@ERROR<>0 
  17184.         goto Error
  17185.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid and status <> 2)
  17186.     if @@ERROR<>0 
  17187.         goto Error
  17188.     delete from sysmergesubsetfilters where pubid = @pubid
  17189.     if @@ERROR<>0 
  17190.         goto Error
  17191.     delete from sysmergesubscriptions where pubid = @pubid and status <> 2
  17192.     if @@ERROR<>0 
  17193.         goto Error
  17194.     delete from sysmergepublications where pubid = @pubid
  17195.     if @@ERROR<>0 
  17196.         goto Error
  17197.     delete from sysmergeschemachange where pubid = @pubid
  17198.     if @@ERROR<>0 
  17199.         goto Error
  17200.  
  17201.     commit tran 
  17202.     return (0)
  17203.  
  17204. Error:
  17205.     rollback tran MSpublicationcleanup
  17206.     commit tran 
  17207.     return (1)
  17208. GO
  17209. exec dbo.sp_MS_marksystemobject sp_MSpublicationcleanup
  17210. go
  17211.  
  17212. grant execute on dbo.sp_MSpublicationcleanup to public
  17213. go
  17214.  
  17215. raiserror('Creating procedure sp_removedbreplication', 0,1)
  17216. GO
  17217.  
  17218. create procedure sp_cleanupdbreplication
  17219. AS
  17220. set nocount on
  17221.  
  17222. declare @pubid            uniqueidentifier
  17223. declare @artid            uniqueidentifier
  17224. declare @retcode        int
  17225.  
  17226. if not exists (select name from sysobjects where name='sysmergesubscriptions')
  17227.     return (0)
  17228. declare #RemoveReplication CURSOR LOCAL FAST_FORWARD for 
  17229.     select pubid from sysmergepublications 
  17230. open #RemoveReplication
  17231. fetch #RemoveReplication into @pubid
  17232. while (@@fetch_status<>-1)
  17233. begin
  17234.     /* Clean up the articles for this publication, and delete the row */
  17235.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17236.     while @artid is not null
  17237.         begin
  17238.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  17239.             begin
  17240.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  17241.                 if @retcode<>0 or @@ERROR<>0 
  17242.                 begin
  17243.                     close #RemoveReplication
  17244.                     deallocate #RemoveReplication
  17245.                     return (1)
  17246.                 end
  17247.             end
  17248.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  17249.         set @artid = NULL
  17250.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17251.         end
  17252.     fetch #RemoveReplication into @pubid
  17253. end
  17254. close #RemoveReplication
  17255. deallocate #RemoveReplication
  17256.         
  17257. /* Now clean up any traces in other system tables */
  17258.     
  17259. delete from MSmerge_genhistory 
  17260. delete from MSmerge_replinfo
  17261. delete from sysmergesubsetfilters 
  17262. delete from sysmergesubscriptions 
  17263. delete from sysmergepublications
  17264. delete from sysmergeschemachange
  17265. return (0)
  17266.  
  17267. GO
  17268. exec dbo.sp_MS_marksystemobject sp_cleanupdbreplication
  17269. go
  17270.  
  17271. grant execute on dbo.sp_cleanupdbreplication to public
  17272. go
  17273.  
  17274.  
  17275.  
  17276.  
  17277. raiserror('Creating procedure sp_MSarticlecleanup', 0,1)
  17278. GO
  17279.  
  17280. create procedure sp_MSarticlecleanup
  17281.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  17282. as
  17283.     set nocount on
  17284.     declare @source_table     nvarchar(270)
  17285.     declare @conflict_table nvarchar(270)
  17286.     declare @ownername         sysname
  17287.     declare @objectname     sysname
  17288.     declare @tablenick        int
  17289.     declare @objid             int
  17290.     declare @sync_objid     int
  17291.     declare @view_type        int
  17292.     declare @tsview            nvarchar(50)
  17293.     declare @guidstr        nvarchar(50)
  17294.     declare @csview            nvarchar(50)
  17295.     declare @viewname        nvarchar(270)
  17296.     declare @retcode        smallint
  17297.     declare @qualified_name    nvarchar(270)
  17298.     declare @bi_tablename    sysname
  17299.     declare    @bi_viewname    sysname
  17300.     declare @bi_procname    sysname
  17301.     declare @constraintname    sysname
  17302.     declare @merge_pub_markcolumn_bit int
  17303.     declare @merge_pub_unmarkcolumn_bit int
  17304.  
  17305.     -- to be called after article is set up in a subscriber
  17306.  
  17307.     /*
  17308.     ** Security Check
  17309.     */
  17310.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  17311.     IF @@ERROR <> 0 or @retcode <> 0
  17312.         return (1)
  17313.  
  17314.     select @merge_pub_markcolumn_bit = 0x4000
  17315.     select @merge_pub_unmarkcolumn_bit = ~@merge_pub_markcolumn_bit
  17316.  
  17317.     select @objid = max(objid) from sysmergearticles where artid = @artid
  17318.  
  17319.     -- get owner name, and table name
  17320.     select @objectname = name, @ownername = user_name(uid)
  17321.         from sysobjects    where id = @objid
  17322.  
  17323.     -- construct the qualified table name
  17324.     select @source_table = QUOTENAME(@ownername) + '.' + QUOTENAME(@objectname)
  17325.  
  17326.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  17327.     if @retcode<>0 or @@ERROR<>0 return (1)
  17328.     
  17329.     -- get the insert, update and conflict proc names from sysmergearticles
  17330.     select     @sync_objid = sync_objid, 
  17331.             @view_type = view_type, 
  17332.             @tablenick = nickname,
  17333.             @bi_tablename = object_name(before_image_objid),
  17334.             @bi_viewname = object_name(before_view_objid),
  17335.             @conflict_table = conflict_table 
  17336.         from sysmergearticles where
  17337.             pubid = @pubid and artid = @artid
  17338.  
  17339.     /*
  17340.     ** We are not owner_qualifed this conflict table because it is created by snapshot agent
  17341.     */
  17342.     select @qualified_name = QUOTENAME(@ownername) + '.' + QUOTENAME(@conflict_table)
  17343.  
  17344.     /* Drop the conflict table */
  17345.     if (@conflict_table IS NOT NULL) and exists (select * from sysobjects where
  17346.             name = @conflict_table and type = 'U')
  17347.         begin
  17348.             exec ('drop table ' + @qualified_name)
  17349.             if @@ERROR<>0 return (1)
  17350.         end
  17351.  
  17352.  
  17353.     /* If there is a before image table, drop it and its cleanup proc */
  17354.     if (@bi_tablename is not null)
  17355.         begin
  17356.         set @bi_procname = @bi_tablename + '_clean'
  17357.  
  17358.         if exists (select * from sysobjects where
  17359.             name = @bi_procname and type = 'P')
  17360.             begin
  17361.             exec ('drop proc ' + @bi_procname)
  17362.             if @@ERROR<>0 return (1)
  17363.             end
  17364.         exec ('drop table ' + @bi_tablename)
  17365.         if @@ERROR<>0 return (1)
  17366.         end
  17367.     /* If there is a before image view, drop it */
  17368.     if (@bi_viewname is not null)
  17369.         begin
  17370.         exec ('drop view ' + @bi_viewname)
  17371.         if @@ERROR<>0 return (1)
  17372.         end
  17373.         
  17374.     /* Drop the article procs */
  17375.     exec @retcode=sp_MSdroparticleprocs @pubid, @artid
  17376.     if @@ERROR<>0 or @retcode<>0 return (1)
  17377.  
  17378.     /* Drop the article triggers */
  17379.     exec @retcode=sp_MSdroparticletriggers @source_table
  17380.     if @@ERROR<>0 or @retcode<>0 return (1)
  17381.  
  17382.     exec @retcode=sp_MSunmarkreplinfo @objectname, @ownername
  17383.     if @@ERROR<>0 or @retcode<>0 return (1)
  17384.  
  17385.     /* so that columns can be dropped */
  17386.     update syscolumns set colstat=colstat & @merge_pub_unmarkcolumn_bit where id=@objid
  17387.     if @@ERROR<>0 return (1)
  17388.  
  17389.     /* If the article's has a temporary ( view type = 2) or a permanent view (view_type = 1 ) drop the sync object */
  17390.     if (@view_type = 1 OR @view_type = 2)
  17391.         begin
  17392.             select @viewname = sysobjects.name from sysobjects where 
  17393.                 ObjectProperty (sysobjects.id, 'IsView') = 1 
  17394.                 and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  17395.                 and sysobjects.id = @sync_objid
  17396.             if @viewname IS NOT NULL
  17397.                 begin
  17398.                     select @ownername = user_name(uid) from sysobjects where name=@viewname
  17399.                     set @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@viewname)
  17400.                     exec ('drop view ' + @viewname)
  17401.                     if @@ERROR<>0 return (1)
  17402.                 end
  17403.         end
  17404.  
  17405.     /*
  17406.     ** Drop the views created for MSmerge_contents and MSmerge_tombstone before dropping these two tables
  17407.     */
  17408.     set @csview = 'ctsv_' + @guidstr
  17409.     set @tsview = 'tsvw_' + @guidstr
  17410.     if EXISTS (select * from sysobjects where name=@csview and type='V')
  17411.     BEGIN
  17412.         select @ownername = user_name(uid) from sysobjects where  name=@csview
  17413.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@csview)
  17414.         exec ('drop view ' + @viewname)
  17415.             if @@ERROR<>0 return (1)
  17416.     END
  17417.         
  17418.     if EXISTS (select * from sysobjects where name=@tsview and type='V')
  17419.     BEGIN
  17420.         select @ownername = user_name(uid) from sysobjects where  name=@tsview
  17421.         select @viewname = QUOTENAME(@ownername) + '.' + QUOTENAME(@tsview)
  17422.         exec ('drop view ' + @viewname)
  17423.             if @@ERROR<>0 return (1)
  17424.     END
  17425.  
  17426.     select @constraintname = 'repl_identity_range_pub_' + convert(nvarchar(36), @artid)
  17427.     select @constraintname = REPLACE(@constraintname, '-', '_')
  17428.     if exists (select * from sysobjects where name = @constraintname and xtype='C')
  17429.     begin
  17430.         exec ('alter table '+ @source_table + ' drop constraint ' + @constraintname)
  17431.         if @@ERROR<>0
  17432.             return (1)
  17433.     end
  17434.  
  17435.     select @constraintname = 'repl_identity_range_repub_' + convert(nvarchar(36), @artid)
  17436.     select @constraintname = REPLACE(@constraintname, '-', '_')
  17437.     if exists (select * from sysobjects where name = @constraintname and xtype='C')
  17438.     begin
  17439.         exec ('alter table '+ @source_table + ' drop constraint ' + @constraintname)
  17440.         if @@ERROR<>0
  17441.             return (1)
  17442.     end
  17443.  
  17444.     /* Delete from contents, tombstone, delete conflicts; Ignore errors that occur */
  17445.     delete from MSmerge_contents where tablenick = @tablenick
  17446.     delete from MSmerge_tombstone where tablenick = @tablenick
  17447.     /* Delete rows from MSmerge_genhistory - if this is the last table that refers to them */
  17448.     if not exists (select * from sysmergearticles where nickname = @tablenick and pubid <> @pubid)
  17449.         delete from MSmerge_genhistory where art_nick = @tablenick
  17450.  
  17451.     delete from MSmerge_delete_conflicts where tablenick = @tablenick
  17452.     delete from MSrepl_identity_range where objid=@objid
  17453. GO
  17454.  
  17455. exec dbo.sp_MS_marksystemobject sp_MSarticlecleanup
  17456. go
  17457.  
  17458. grant execute on dbo.sp_MSarticlecleanup to public
  17459. go
  17460.  
  17461. raiserror('Creating procedure sp_MSdroparticleprocs', 0,1)
  17462. GO
  17463.  
  17464. create procedure sp_MSdroparticleprocs
  17465.     (@pubid uniqueidentifier, @artid uniqueidentifier)
  17466. as
  17467.     set nocount on
  17468.     declare @ins_procname     sysname
  17469.     declare @upd_procname     sysname
  17470.     declare @conf_procname     sysname
  17471.     declare @sel_procname    sysname
  17472.     declare @tmp_procname    nvarchar(260)
  17473.     declare @view_sel_proc     nvarchar(290)
  17474.     declare @owner            sysname
  17475.     declare @objid            int
  17476.     
  17477.     -- get the insert, update and conflict proc names from sysmergearticles
  17478.     select @ins_procname = insert_proc,    
  17479.             @upd_procname = update_proc, 
  17480.             @sel_procname = select_proc,
  17481.             @conf_procname = ins_conflict_proc,
  17482.             @view_sel_proc = view_sel_proc,
  17483.             @objid = objid
  17484.         from sysmergearticles where
  17485.             pubid = @pubid and artid = @artid
  17486.  
  17487.     if (@ins_procname IS NOT NULL) and exists (select * from sysobjects where
  17488.             name = @ins_procname and type = 'P')
  17489.         begin
  17490.             select @owner = user_name(uid) from sysobjects where name=@ins_procname
  17491.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@ins_procname)
  17492.             exec ('drop proc ' + @tmp_procname)
  17493.             if @@ERROR<>0 return (1)
  17494.             update sysmergearticles set insert_proc = NULL where pubid=@pubid and artid=@artid
  17495.         end
  17496.     if (@upd_procname IS NOT NULL) and exists (select * from sysobjects where
  17497.             name = @upd_procname and type = 'P')
  17498.         begin
  17499.             select @owner = user_name(uid) from sysobjects where name=@upd_procname
  17500.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@upd_procname)
  17501.             exec ('drop proc ' + @tmp_procname)
  17502.             if @@ERROR<>0 return (1)
  17503.             update sysmergearticles set update_proc = NULL where pubid=@pubid and artid=@artid
  17504.  
  17505.         end
  17506.     if (@sel_procname IS NOT NULL) and exists (select * from sysobjects where
  17507.             name = @sel_procname and type = 'P')
  17508.         begin
  17509.             select @owner = user_name(uid) from sysobjects where name=@sel_procname
  17510.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@sel_procname)
  17511.             exec ('drop proc ' + @tmp_procname)
  17512.             if @@ERROR<>0 return (1)
  17513.             update sysmergearticles set select_proc = NULL where pubid=@pubid and artid=@artid
  17514.         end
  17515.  
  17516.     if (@view_sel_proc IS NOT NULL) and exists (select * from sysobjects where
  17517.             name = @view_sel_proc and type = 'P')
  17518.         begin
  17519.             select @owner = user_name(uid) from sysobjects where name=@view_sel_proc
  17520.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@view_sel_proc)
  17521.             exec ('drop proc ' + @tmp_procname)
  17522.             if @@ERROR<>0 return (1)
  17523.             update sysmergearticles set view_sel_proc = NULL where pubid=@pubid and artid=@artid
  17524.         end
  17525.  
  17526.     if (@conf_procname IS NOT NULL) and    not exists (select * from sysmergearticles where
  17527.             artid=@artid and pubid<>@pubid) and exists (select * from sysobjects where
  17528.             name = @conf_procname and type = 'P')
  17529.         begin
  17530.             select @owner = user_name(uid) from sysobjects where name=@conf_procname
  17531.             select @tmp_procname = QUOTENAME(@owner) + '.' + QUOTENAME(@conf_procname)
  17532.             exec ('drop proc ' + @tmp_procname)
  17533.             if @@ERROR<>0 return (1)
  17534.             update sysmergearticles set ins_conflict_proc = NULL where pubid=@pubid and artid=@artid
  17535.         end
  17536.     
  17537.     return 0        
  17538.  
  17539. GO
  17540.  
  17541. exec dbo.sp_MS_marksystemobject sp_MSdroparticleprocs
  17542. go
  17543.  
  17544. raiserror('Creating procedure sp_MSdroparticletriggers', 0,1)
  17545. GO
  17546.  
  17547. /*
  17548. ** We need to qualify sysmergearticle with pubid
  17549. */
  17550. create procedure sp_MSdroparticletriggers
  17551.     (@source_table nvarchar(270),
  17552.      @table_owner    sysname = NULL)
  17553. as
  17554.     set nocount on
  17555.     declare @instrigger     nvarchar(270)
  17556.     declare @updtrigger     nvarchar(270)
  17557.     declare @deltrigger     nvarchar(270)
  17558.     declare @retcode        int
  17559.     declare @owner            sysname
  17560.     declare @artid            uniqueidentifier
  17561.     declare @guidstr        nvarchar(32)
  17562.  
  17563.     -- PARSENAME VARS
  17564.     declare      @UnqualName      sysname  --rightmost name node
  17565.     declare      @QualName1       sysname  
  17566.     -- END PARSENAME VARS
  17567.  
  17568.     select @UnqualName = PARSENAME(@source_table, 1)
  17569.     select @QualName1 = PARSENAME(@source_table, 2)
  17570.     if @UnqualName IS NULL
  17571.          return 1
  17572.     if @QualName1 is not NULL
  17573.         select @owner = @QualName1
  17574.             else if @table_owner is not NULL 
  17575.                 select @owner = @table_owner
  17576.                     else select @owner='dbo'
  17577.     
  17578.     select @artid = artid from sysmergearticles where objid = object_id(@source_table)
  17579.  
  17580.     exec @retcode=sp_MSguidtostr @artid, @guidstr out
  17581.     if @retcode<>0 or @@ERROR<>0 return (1)
  17582.  
  17583.     select @instrigger = QUOTENAME(@owner) + '.ins_' + @guidstr
  17584.     select @updtrigger = QUOTENAME(@owner) + '.upd_' + @guidstr
  17585.     select @deltrigger = QUOTENAME(@owner) + '.del_' + @guidstr
  17586.     
  17587. /*    
  17588.     select @instrigger = sysobjects.name from sysobjects where 
  17589.         ObjectProperty (sysobjects.id, 'ExecIsInsertTrigger') = 1 
  17590.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  17591.         and parent_obj = OBJECT_ID(@source_table) 
  17592.  
  17593.     select @updtrigger = sysobjects.name from sysobjects where 
  17594.         ObjectProperty (sysobjects.id, 'ExecIsUpdateTrigger') = 1 
  17595.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  17596.         and parent_obj = OBJECT_ID(@source_table) 
  17597.  
  17598.     select @deltrigger = sysobjects.name from sysobjects where 
  17599.         ObjectProperty (sysobjects.id, 'ExecIsDeleteTrigger') = 1 
  17600.         and ObjectProperty (sysobjects.id, 'IsMSShipped') = 1 
  17601.         and parent_obj = OBJECT_ID(@source_table) 
  17602. */
  17603.  
  17604.     if object_id(@instrigger) is not NULL
  17605.         begin
  17606.             exec ('drop trigger ' + @instrigger)
  17607.             if @@ERROR<>0 return (1)
  17608.         end
  17609.     if object_id(@updtrigger) is not NULL
  17610.         begin
  17611.             exec ('drop trigger ' + @updtrigger)
  17612.             if @@ERROR<>0 return (1)
  17613.         end
  17614.     if object_id(@deltrigger) IS NOT NULL
  17615.         begin
  17616.             exec ('drop trigger ' + @deltrigger)
  17617.             if @@ERROR<>0 return (1)
  17618.         end
  17619.  
  17620.     return 0
  17621. GO
  17622.  
  17623. exec dbo.sp_MS_marksystemobject sp_MSdroparticletriggers
  17624. go
  17625. grant execute on dbo.sp_MSdroparticletriggers to public
  17626.  
  17627. raiserror('Creating procedure sp_mergesubscription_cleanup', 0,1)
  17628. GO
  17629.  
  17630. CREATE PROCEDURE sp_mergesubscription_cleanup (
  17631.     @publisher        sysname,
  17632.     @publisher_db    sysname,
  17633.     @publication     sysname
  17634.     ) AS
  17635.     declare @pubid                 uniqueidentifier
  17636.     declare @artid                 uniqueidentifier
  17637.     declare @retcode            smallint
  17638.     declare @subscription_type  int
  17639.     declare @objid              int
  17640.     declare @objectname         sysname
  17641.     declare @objectowner        sysname
  17642.  
  17643.     /*
  17644.     ** if there is nothing to cleanup, then just return.
  17645.     */
  17646.     if not exists (select * from sysobjects where name='sysmergesubscriptions')
  17647.         return (0)
  17648.         
  17649.     /* This only gets called after database is enable to subscribe, so sysmergepublications should exist */
  17650.     select @pubid = pubid FROM sysmergepublications 
  17651.         WHERE name = @publication and UPPER(publisher)=UPPER(@publisher) and publisher_db=@publisher_db
  17652.  
  17653.     /* Normal case - nothing to cleanup, just return */
  17654.     if @pubid is null
  17655.         return (1)
  17656.  
  17657.     select @subscription_type = subscription_type from sysmergesubscriptions where pubid=@pubid and subid<>pubid
  17658.  
  17659.     /* This procedure is not intended to be used for cleanning-up pull/anonymous subscriptions */
  17660.     if @subscription_type > 0
  17661.         begin
  17662.             raiserror(20091, 16, -1)
  17663.             return (1)
  17664.         end
  17665.  
  17666.     /* Clean up the articles for this publication, and delete the row */
  17667.     select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17668.     while @artid is not null
  17669.         begin
  17670.         if not exists (select * from sysmergearticles WHERE artid = @artid and pubid <> @pubid)
  17671.             begin
  17672.                 exec @retcode=sp_MSarticlecleanup @pubid, @artid
  17673.                 if @retcode<>0 or @@ERROR<>0 return (1)
  17674.             end
  17675.         delete from sysmergearticles where artid = @artid and pubid = @pubid
  17676.         set @artid = NULL
  17677.         select @artid = artid FROM sysmergearticles WHERE pubid = @pubid
  17678.         end
  17679.         
  17680.     /* Cleanup the schema articles */
  17681.  
  17682.     /* Unmark all schema article objects unconditionally */
  17683.     if exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  17684.     begin
  17685.         declare hschemaarticle_cur cursor local fast_forward for
  17686.             select destination_object, destination_owner from sysmergeschemaarticles where
  17687.             pubid = @pubid 
  17688.         for read only
  17689.         open hschemaarticle_cur
  17690.         fetch hschemaarticle_cur into @objectname, @objectowner
  17691.         while (@@fetch_status<>-1)
  17692.         begin
  17693.                 -- Ignore errors
  17694.                 exec  sp_MSunmarkschemaobject @objectname, @objectowner    
  17695.                 fetch hschemaarticle_cur into @objectname, @objectowner
  17696.         end
  17697.         close hschemaarticle_cur
  17698.         deallocate hschemaarticle_cur
  17699.  
  17700.         /* Delete all schema article rows for this publication*/
  17701.         delete from sysmergeschemaarticles where pubid = @pubid
  17702.     end
  17703.  
  17704.     /* 
  17705.     ** Make sure you NULL out gen_cur for other articles that share this table 
  17706.     ** since we are deleting the genhistroy row for that generation 
  17707.     */
  17708.     update sysmergearticles set gen_cur=NULL where gen_cur in
  17709.         (select generation from MSmerge_genhistory where pubid = @pubid)
  17710.  
  17711.     /* Now clean up any traces in other system tables */
  17712.     delete from MSmerge_genhistory where pubid = @pubid 
  17713.     delete from MSmerge_replinfo where repid in (select subid from sysmergesubscriptions where pubid = @pubid)
  17714.     delete from sysmergesubscriptions where pubid = @pubid
  17715.     delete from sysmergepublications where pubid = @pubid
  17716.     delete from sysmergeschemachange where pubid = @pubid
  17717.     /* 
  17718.     ** If last subscription is dropped and the DB is not enabled for publishing,
  17719.     ** then remove the merge system tables
  17720.     */
  17721.     IF (not exists (select * from sysmergesubscriptions )) 
  17722.         AND (select category & 4 FROM master..sysdatabases WHERE name = DB_NAME() collate database_default )=0
  17723.     BEGIN
  17724.         execute @retcode = dbo.sp_MSdrop_mergesystables
  17725.         if @@ERROR <> 0 or @retcode <> 0
  17726.         begin
  17727.             return (1)
  17728.         end
  17729.     END    
  17730. GO
  17731. exec dbo.sp_MS_marksystemobject sp_mergesubscription_cleanup
  17732. go
  17733. grant execute on dbo.sp_mergesubscription_cleanup to public
  17734.  
  17735. raiserror('Creating procedure sp_subscription_cleanup', 0,1)
  17736. GO
  17737. CREATE PROCEDURE sp_subscription_cleanup (
  17738.     @publisher        sysname,
  17739.     @publisher_db    sysname,
  17740.     @publication    sysname = NULL,
  17741.     @reserved        nvarchar(10) = NULL
  17742. )
  17743. AS
  17744. BEGIN
  17745.  
  17746.     declare @object_name sysname
  17747.             ,@object_type char(2)
  17748.             ,@independent_agent bit
  17749.             ,@retcode int
  17750.             ,@synctran_bit int
  17751.             ,@parent_obj int
  17752.             ,@object_id int
  17753.             ,@cmd nvarchar(4000)
  17754.  
  17755.     select @synctran_bit            = 256
  17756.  
  17757.     /*
  17758.     ** Security Check
  17759.     */
  17760.  
  17761.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  17762.     IF @@ERROR <> 0 or @retcode <> 0
  17763.         RETURN(1)
  17764.  
  17765.     if @publication = '' OR @publication is NULL
  17766.         select @independent_agent = 0
  17767.     else
  17768.         select @independent_agent = 1
  17769.  
  17770.     IF exists (select name from sysobjects where name = 'MSreplication_objects')
  17771.     BEGIN
  17772.         declare object_cursor CURSOR LOCAL FAST_FORWARD for 
  17773.             select DISTINCT object_name, object_type from MSreplication_objects o
  17774.                     where (UPPER(o.publisher) = UPPER(@publisher) and
  17775.                         o.publisher_db = @publisher_db and
  17776.                         o.publication = @publication) or
  17777.                         @reserved = 'drop_all'
  17778.  
  17779.         OPEN object_cursor
  17780.         FETCH object_cursor INTO @object_name, @object_type
  17781.          WHILE (@@fetch_status <> -1)
  17782.               BEGIN
  17783.                   IF @object_type = 'T' 
  17784.                   begin
  17785.                     select @parent_obj = NULL
  17786.                     select @parent_obj = parent_obj, @object_id = id from
  17787.                         sysobjects where name = @object_name 
  17788.                     if @parent_obj is not null
  17789.                     begin
  17790.                         -- Unmark synctran bit
  17791.                         update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  17792.                             id = @parent_obj and
  17793.                             (replinfo & @synctran_bit) <> 0
  17794.                         IF @@ERROR <> 0 
  17795.                             GOTO UNDO
  17796.                         exec @retcode = dbo.sp_MSdrop_object 
  17797.                             @object_id = @object_id
  17798.                         if @retcode <> 0 or @@error <> 0
  17799.                             goto UNDO
  17800.  
  17801.                         -- Clean up identity range entry
  17802.                         -- Since we only support one trigger per subscriber table
  17803.                         -- we assume identity range row can not be reused by multiple
  17804.                         -- subscriptions.
  17805.                         IF EXISTS(select * from sysobjects where type='U' and name = 'MSsub_identity_range')
  17806.                         BEGIN
  17807.                             if exists (select * from MSsub_identity_range where objid = @parent_obj)
  17808.                             begin
  17809.                                 -- Drop the identity range constraits.
  17810.                                 exec @retcode = dbo.sp_MSreseed
  17811.                                     @objid =  @parent_obj,
  17812.                                     -- range or seed can be anything
  17813.                                     @next_seed = 10,
  17814.                                     @range = 10,
  17815.                                     @is_publisher = -1,
  17816.                                     @check_only = 1,
  17817.                                     @drop_only = 1
  17818.                                 IF @retcode <> 0 or @@ERROR <> 0 
  17819.                                     GOTO UNDO
  17820.  
  17821.                                 delete MSsub_identity_range where objid = @parent_obj
  17822.                                 IF @@ERROR <> 0 
  17823.                                     GOTO UNDO
  17824.                             end
  17825.  
  17826.                             IF NOT EXISTS (SELECT * FROM MSsub_identity_range)
  17827.                             BEGIN
  17828.                                 DROP TABLE MSsub_identity_range
  17829.                                 IF @@ERROR <> 0 
  17830.                                     GOTO UNDO
  17831.                             END
  17832.                         END
  17833.                     end
  17834.                   end
  17835.                   delete from MSreplication_objects where object_name=@object_name
  17836.                   FETCH object_cursor INTO @object_name, @object_type
  17837.               END
  17838.         CLOSE object_cursor
  17839.         DEALLOCATE object_cursor
  17840.         
  17841.         if not exists (select * from MSreplication_objects) 
  17842.         begin
  17843.             drop table MSreplication_objects
  17844.             IF @@ERROR <> 0 
  17845.                 GOTO UNDO
  17846.         end
  17847.         
  17848.     END
  17849.  
  17850.     --
  17851.     -- cleanup queued conflict tables
  17852.     --
  17853.     IF exists (select name from dbo.sysobjects where name = 'MSsubscription_agents')
  17854.     BEGIN
  17855.         declare        @agent_id int
  17856.                     ,@cft_table sysname
  17857.                     ,@owner sysname
  17858.  
  17859.         --
  17860.         -- first get the agent(s) for this queued subscription(s) and 
  17861.         -- 
  17862.         declare #agent_cursor CURSOR LOCAL FAST_FORWARD for 
  17863.             select id from dbo.MSsubscription_agents 
  17864.             where ((UPPER(publisher) = UPPER(@publisher) and 
  17865.                     publisher_db = @publisher_db and 
  17866.                     publication = @publication) or (@reserved = 'drop_all')) and
  17867.                     update_mode in (2,3,4,5)
  17868.  
  17869.         open #agent_cursor
  17870.         fetch #agent_cursor into @agent_id
  17871.         while (@@fetch_status != -1)
  17872.         begin
  17873.             --
  17874.             -- drop the conflict table for each article in this subscription
  17875.             --
  17876.             if exists (select name from dbo.sysobjects where name = 'MSsubscription_articles')
  17877.             begin
  17878.             
  17879.                 declare #object_cursor CURSOR LOCAL FAST_FORWARD for 
  17880.                     select owner, cft_table from dbo.MSsubscription_articles
  17881.                     where agent_id = @agent_id
  17882.  
  17883.                 OPEN #object_cursor
  17884.                 FETCH #object_cursor INTO @owner, @cft_table
  17885.                 WHILE (@@fetch_status != -1)
  17886.                 BEGIN
  17887.                     --
  17888.                     -- drop the conflict table(s) for this article - ignore errors
  17889.                     --
  17890.                     select @cmd = case 
  17891.                         when (@owner IS NULL) then
  17892.                             N'if exists (select * from dbo.sysobjects where name = N''' + 
  17893.                             master.dbo.fn_MSgensqescstr(@cft_table) collate database_default + ''') drop table ' + 
  17894.                             quotename(master.dbo.fn_MSgensqescstr(@cft_table)) collate database_default
  17895.                         else
  17896.                             N'if exists (select * from dbo.sysobjects where name = N''' + 
  17897.                             master.dbo.fn_MSgensqescstr(@cft_table) collate database_default + ''') drop table ' + 
  17898.                             quotename(master.dbo.fn_MSgensqescstr(@owner)) collate database_default + N'.' +
  17899.                             quotename(master.dbo.fn_MSgensqescstr(@cft_table)) collate database_default
  17900.                         end
  17901.                     execute ( @cmd )
  17902.  
  17903.                     -- get next row
  17904.                     FETCH #object_cursor INTO @owner, @cft_table
  17905.                 END
  17906.                 CLOSE #object_cursor
  17907.                 DEALLOCATE #object_cursor
  17908.  
  17909.                 --
  17910.                 -- delete entries from MSsubscription_articles for this agent id
  17911.                 --
  17912.                 delete dbo.MSsubscription_articles where agent_id = @agent_id
  17913.  
  17914.                 --
  17915.                 -- drop MSsubscription_articles if empty (should we do it)
  17916.                 -- 
  17917.                 IF NOT EXISTS (SELECT * FROM dbo.MSsubscription_articles)
  17918.                 BEGIN
  17919.                     DROP TABLE dbo.MSsubscription_articles
  17920.                     IF @@ERROR != 0 
  17921.                         GOTO UNDO
  17922.                 END
  17923.             end
  17924.  
  17925.             --
  17926.             -- get the next agent
  17927.             --
  17928.             fetch #agent_cursor into @agent_id
  17929.         end
  17930.         close #agent_cursor
  17931.         deallocate #agent_cursor
  17932.     END
  17933.  
  17934.     --
  17935.     -- clean discarded queued transactions
  17936.     --
  17937.     if exists (select name from dbo.sysobjects where name = 'MSreplication_queue')
  17938.     begin
  17939.         delete dbo.MSreplication_queue
  17940.         where (UPPER(publisher) = UPPER(@publisher) and 
  17941.                 publisher_db = @publisher_db and 
  17942.                 publication = @publication) or 
  17943.                 @reserved = 'drop_all'
  17944.     end
  17945.     
  17946.     IF exists (select name from sysobjects where name = 'MSreplication_subscriptions')
  17947.     BEGIN
  17948.     delete from MSreplication_subscriptions 
  17949.         where (UPPER(publisher) = UPPER(@publisher) AND
  17950.               publisher_db = @publisher_db AND
  17951.               -- Drop the subscription as long as the publication name matches even if
  17952.               -- the publication is not independent agent
  17953.               -- This behaviour is expected by sp_droppullsubscription
  17954.               -- -- independent_agent = @independent_agent and 
  17955.               ((@independent_agent=0 and independent_agent = 0) or 
  17956.               publication = @publication))
  17957.               or @reserved = 'drop_all'
  17958.  
  17959.         IF NOT EXISTS (SELECT * FROM MSreplication_subscriptions)
  17960.         BEGIN
  17961.             DROP TABLE MSreplication_subscriptions
  17962.             IF @@ERROR <> 0 
  17963.                 GOTO UNDO
  17964.         END
  17965.     END
  17966.  
  17967.  
  17968.     IF exists (select name from sysobjects where name = 'MSsubscription_agents')
  17969.     BEGIN
  17970.         delete from MSsubscription_agents
  17971.         where (UPPER(publisher) = UPPER(@publisher) AND
  17972.               publisher_db = @publisher_db AND
  17973.               -- Drop the subscription as long as the publication name matches even if
  17974.               -- the publication is not independent agent
  17975.               -- This behaviour is expected by sp_droppullsubscription
  17976.               (publication = @publication or
  17977.                (@independent_agent=0 and publication = N'ALL')))
  17978.               or @reserved = 'drop_all'
  17979.  
  17980.         -- Delete the agent entry if no corresponding rows found in MSreplication_subscription
  17981.         -- table.
  17982.         -- This is to cleanup share agent entry.
  17983.         -- This behaviour is expected by sp_droppullsubscription
  17984.         if object_id('MSreplication_subscriptions') is not null
  17985.         begin
  17986.             if not exists (select * from MSreplication_subscriptions s where
  17987.                     s.publisher = @publisher and
  17988.                     s.publisher_db = @publisher_db and
  17989.                     s.independent_agent = 0)
  17990.                 delete from MSsubscription_agents where
  17991.                     publisher = @publisher and
  17992.                     publisher_db = @publisher_db and
  17993.                     publication = N'ALL'
  17994.         end
  17995.         else
  17996.             delete  MSsubscription_agents
  17997.  
  17998.         IF NOT EXISTS (SELECT * FROM MSsubscription_agents)
  17999.         BEGIN
  18000.             DROP TABLE MSsubscription_agents
  18001.             IF @@ERROR <> 0 
  18002.                 GOTO UNDO
  18003.         END
  18004.     END
  18005.  
  18006.     IF EXISTS(select * from sysobjects where type=N'U' and name = 'MSsubscription_properties')
  18007.     BEGIN
  18008.         DELETE FROM MSsubscription_properties 
  18009.         WHERE (UPPER(publisher) = UPPER(@publisher)    AND
  18010.         publisher_db  = @publisher_db AND
  18011.         publication = @publication) 
  18012.         or @reserved = 'drop_all'
  18013.  
  18014.         IF @@ERROR <> 0 
  18015.             GOTO UNDO
  18016.  
  18017.         IF NOT EXISTS (SELECT * FROM MSsubscription_properties)
  18018.         BEGIN
  18019.             exec @retcode = dbo.sp_MSsub_cleanup_prop_table
  18020.             IF @@ERROR <> 0 or @retcode <> 0
  18021.                 GOTO UNDO
  18022.         END
  18023.     END
  18024.  
  18025.     -- Ignore errors.
  18026.     exec dbo.sp_MSsub_cleanup_orphans
  18027.     
  18028.     return (0)
  18029.             
  18030. UNDO:
  18031.     return(1)
  18032. END
  18033. GO
  18034. exec dbo.sp_MS_marksystemobject sp_subscription_cleanup 
  18035. go
  18036.  
  18037.  
  18038. raiserror('Creating procedure sp_get_distributor', 0,1)
  18039. go
  18040.  
  18041. -- Called by the UI to find out if the distributor is installed without doing RPC.
  18042. CREATE PROCEDURE sp_get_distributor 
  18043. AS
  18044.     SET NOCOUNT ON
  18045.  
  18046.     /*
  18047.     ** Declarations.
  18048.     */
  18049.     DECLARE @distributor sysname
  18050.     DECLARE @installed bit
  18051.     declare @distdb_installed bit
  18052.     declare @is_distpublisher bit
  18053.     declare @has_remote_distpublisher bit
  18054.      declare @distbit int
  18055.  
  18056.     SELECT @distbit = 16
  18057.        
  18058.     SELECT @distributor = datasource FROM master..sysservers
  18059.         WHERE srvstatus & 8 <> 0
  18060.  
  18061.     if @distributor is not null
  18062.         select @installed = 1
  18063.     else
  18064.         select @installed = 0
  18065.  
  18066.     if UPPER(@distributor) = UPPER(@@servername)
  18067.     begin
  18068.         if exists (select * from msdb.dbo.MSdistributiondbs) 
  18069.             select @distdb_installed = 1
  18070.         else
  18071.             select @distdb_installed = 0
  18072.  
  18073.         if exists (select * from msdb..MSdistpublishers where UPPER(name) = UPPER(@@servername) collate database_default)
  18074.             select @is_distpublisher = 1
  18075.         else
  18076.             select @is_distpublisher = 0
  18077.  
  18078.         if exists (select * from msdb..MSdistpublishers where UPPER(name) <> UPPER(@@servername) collate database_default)
  18079.             select @has_remote_distpublisher = 1
  18080.         else
  18081.             select @has_remote_distpublisher = 0
  18082.     end
  18083.     else
  18084.     begin
  18085.         select @distdb_installed = 0
  18086.         select @has_remote_distpublisher = 0    
  18087.         select @is_distpublisher = 0
  18088.     end
  18089.  
  18090.     select 'installed' = @installed, 'distribution server' = @distributor,
  18091.             'distribution db installed' = @distdb_installed,
  18092.             'is distribution publisher' = @is_distpublisher,
  18093.             'has remote distribution publisher' = @has_remote_distpublisher
  18094. GO
  18095.  
  18096. exec dbo.sp_MS_marksystemobject sp_get_distributor
  18097. go
  18098.  
  18099.  
  18100. -- Called by sp_addrolemember
  18101. raiserror('Creating procedure sp_MSrepl_addrolemember', 0,1)
  18102. go
  18103. CREATE PROCEDURE sp_MSrepl_addrolemember
  18104.     @rolename       sysname,
  18105.     @membername     sysname
  18106. AS
  18107.     -- SETUP RUNTIME OPTIONS / DECLARE VARIABLES --
  18108.     set    nocount on
  18109.     
  18110.     return(0)
  18111.  
  18112. go        
  18113.  
  18114. exec dbo.sp_MS_marksystemobject sp_MSrepl_addrolemember
  18115. go
  18116.  
  18117. -- Called by sp_droprolemember
  18118. raiserror('Creating procedure sp_MSrepl_droprolemember', 0,1)
  18119. go
  18120. CREATE PROCEDURE sp_MSrepl_droprolemember
  18121.     @rolename       sysname,
  18122.     @membername     sysname
  18123. AS
  18124.     set    nocount on
  18125.     return(0)
  18126. go        
  18127.  
  18128. exec dbo.sp_MS_marksystemobject sp_MSrepl_droprolemember
  18129. go
  18130.  
  18131. raiserror('Creating procedure sp_table_validation', 0,1)
  18132. go
  18133.  
  18134. create procedure sp_table_validation
  18135. @table sysname,                -- table name or sync object name
  18136. @expected_rowcount bigint = NULL OUTPUT,
  18137. @expected_checksum numeric = NULL OUTPUT,
  18138. @rowcount_only smallint = 1,
  18139. /* 
  18140. The @rowcount_only param is overloaded for shiloh release due to backward compatibility concerns.
  18141. In shiloh, the checksum functionality has changed.   So 7.0 subscribers will have the old checksum 
  18142. routines, which generate different CRC values, and do not have functionality for vertical partitions,
  18143. or logical table structures where column offsets differ (due to ALTER TABLEs that DROP and ADD columns).
  18144.  
  18145. In 7.0, this was a bit column.  0 meant do not do just a rowcount - do a checksum.  1 meant just do a 
  18146. rowcount.
  18147.  
  18148. For Shiloh, this parameter is changed to a smallint.  The name "rowcount_only" is now a 
  18149. misnomer given the overloaded functionality.  It is really a "type of check requested"
  18150. parameter.   But, the old name is retained for backward compatibility.   It can take 
  18151. these values:
  18152.  
  18153. 0 - Do a 7.0 compatible checksum
  18154. 1 - Do a rowcount check only (remains the default)
  18155. 2 - Use new Shiloh checksum functionality.  
  18156.  
  18157. Note that because 7.0 subscribers will 
  18158. take this parameter as a bit type, not a smallint, it will be interpreted as simply
  18159. ON.  That means that passing a 2, and having a 7.0 subscriber, will result in the 7.0
  18160. subscriber doing only rowcount validation.   The Shiloh subscribers will do both
  18161. rowcount and checksum.  If you want 7.0 subscribers to do checksum validation, use 
  18162. the value of 0 for this parameter.   Shiloh subscribers can do the 7.0 compatible 
  18163. checksum, but that checksum has the same 7.0 limitations for vertical partitions 
  18164. and differences in physical table structure.)
  18165.  
  18166. */
  18167.  
  18168. @owner    sysname = NULL,
  18169. @full_or_fast tinyint = 2,        -- full (value 0) does COUNT(*) 
  18170.                     -- fast (value 1) uses sysindexes.rowcnt if table (not view); 
  18171.                     -- conditional fast (VALUE 2) , first tries fast method, but
  18172.                     -- reverts to full if fast method shows differences.
  18173. @shutdown_agent bit = 0,         -- If 1 will raise error 20578, which will signal replication agent to shutdown
  18174. @table_name sysname    = NULL,        -- table name of sync object or the table name for output message,
  18175. @column_list nvarchar(4000) = NULL     -- the list of columns - that way the user can skip computed columns etc
  18176.  
  18177. as
  18178.  
  18179. set nocount on
  18180.  
  18181. declare @num_rows bigint
  18182. declare @checksum numeric
  18183. declare @checksum_string varchar(100)
  18184. declare @expected_checksum_string varchar(21)
  18185. declare @rowcount_string varchar(21)
  18186. declare @exp_rowcount_string varchar(21)
  18187. declare @width int
  18188. declare @qualified_table_name nvarchar(262)  -- two names plus []'s and a .
  18189. declare @temp_table_used bit
  18190. declare @retstatus int
  18191. declare @failed_fast tinyint
  18192. declare @min_indid int
  18193. declare @asked_for_exp_checksum tinyint
  18194. declare @asked_for_exp_rows tinyint
  18195.  
  18196.  
  18197.  
  18198. SET @retstatus=0    -- initialize to SUCCESS
  18199. SET @failed_fast=0
  18200.  
  18201.  
  18202. if (@expected_checksum IS NULL AND isnull(@rowcount_only,-9999) <> 1 )  -- Wants an expected checksum value
  18203.     SET @asked_for_exp_checksum=1
  18204. ELSE
  18205.     SET @asked_for_exp_checksum=0
  18206.  
  18207.  
  18208. if (@expected_rowcount IS NULL)  -- Wants an expected rowcount value
  18209.     SET @asked_for_exp_rows=1
  18210. ELSE
  18211.     SET @asked_for_exp_rows=0
  18212.  
  18213. -- Only values 0,1,2 make sense for @rowcount_only. 
  18214. if (@rowcount_only NOT BETWEEN 0 and 2)
  18215.     BEGIN
  18216.     -- msg 20543 says that @rowcount_only must be 0,1,2 and explains the values.
  18217.     RAISERROR (20543,16,-1,@qualified_table_name)
  18218.     SET @retstatus=1
  18219.     return @retstatus
  18220.     END
  18221.  
  18222. -- RHS:  
  18223. -- Some states do not make sense.  For example,  it does not make sense to ask for conditional
  18224. -- fast row count checking, yet not provide an expected value.  If this is done, provide a warning
  18225. -- message and use fast checking method.
  18226. if (@full_or_fast = 2 AND @expected_rowcount IS NULL)
  18227.     BEGIN
  18228.     -- (20559,10,0,'Conditional Fast Rowcount method requested without specifying an expected count. Fast method will be used.', 1033)
  18229.     raiserror (20559, 10, -1)
  18230.     SET @full_or_fast = 1
  18231.     END
  18232.  
  18233. -- Another state that doesn't make sense is to pass an expected checksum value, yet
  18234. -- ask for rowcount only validation
  18235. if (@expected_checksum IS NOT NULL AND @rowcount_only = 1)
  18236.     BEGIN
  18237.     -- (Msg 20560,10,0,'An expected checksum value was passed, but checksums will not be compared because rowcount only checking was requested.', 1033)
  18238.     raiserror (20560, 10, -1)
  18239.     SET @expected_checksum = NULL
  18240.     END
  18241.  
  18242.  
  18243. if @owner is null
  18244. begin
  18245.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  18246.         set @qualified_table_name = '[' + @table + ']'
  18247.     else
  18248.         set @qualified_table_name = @table
  18249. end
  18250. else
  18251. begin
  18252.     if left(ltrim(rtrim(@table)), 1) <> '[' or right(ltrim(rtrim(@table)), 1) <> ']'
  18253.         set @qualified_table_name = '[' + @owner + '].[' + @table + ']'
  18254.     else
  18255.         set @qualified_table_name = '[' + @owner + '].' + @table
  18256. end
  18257.  
  18258. IF (OBJECT_ID(@qualified_table_name) IS NULL)
  18259.     -- No such object.  Return with error.
  18260.     BEGIN
  18261.     -- Msg (20585,10,0,'Object '%s' does not exist.  Exiting validation check.', 1033)  
  18262.     RAISERROR (20585,16,-1,@qualified_table_name)
  18263.     SET @retstatus=1
  18264.     return @retstatus
  18265.     END
  18266.  
  18267. -- If the object is a table (not view) and fast checking (1) requested,
  18268. -- then get rowcount from sysindexes, rather than scanning.
  18269. -- Fast rowcount method gets value from sysindexes - and the row_cnt value is only maintained for tables.
  18270.  
  18271. IF (SELECT @full_or_fast) > 0    -- IF Fast row checking asked for
  18272.     AND 
  18273.    (SELECT OBJECTPROPERTY(OBJECT_ID(@qualified_table_name),'IsTable')) > 0  -- Must be a table, not a view
  18274.  
  18275.     BEGIN
  18276.         -- Do the fast rowcount method
  18277.         -- Temporarily put a SHARE lock on table to ensure no simultaneous updates going on
  18278.         -- Minimizes chances of getting an out of date value from sysindexes.   True that
  18279.         -- it reduces concurrency, but if the fast method doesnt work the user will very likely
  18280.         -- go do the full method, which will be much more costly.   Better I think to take a little more cost here
  18281.         -- and hopefully get a good number.   The @foo variable is used so that its an
  18282.         -- assignment and doesn't make another result set get returned.
  18283.  
  18284.         BEGIN TRAN
  18285.         EXEC ('DECLARE @foo int SELECT @foo=1 FROM ' + @qualified_table_name + ' (TABLOCK HOLDLOCK) WHERE 1=2')
  18286.         SELECT @num_rows=rowcnt,@min_indid=indid FROM sysindexes WHERE id=OBJECT_ID(@qualified_table_name)and indid < 2
  18287.         COMMIT TRAN
  18288.     END
  18289.  
  18290. ELSE 
  18291.     SET @full_or_fast = 0   -- Full checking will be used, regardless of whether it was requested
  18292.  
  18293. --    set the output name if not set
  18294.     if (@table_name IS NULL)
  18295.         SELECT @table_name = @table
  18296.  
  18297. -- If fast row checking was used, and request for rowcount check only, we're done.
  18298. if (@full_or_fast = 1  AND  @rowcount_only = 1) 
  18299.     GOTO ROWCOUNT_MSG
  18300.     
  18301. -- If conditional fast row checking was used, and request for rowcount check only, 
  18302. -- we're also done IFF rows and expected rows match.
  18303. if (@full_or_fast = 2  AND  @rowcount_only = 1 
  18304.     AND @expected_rowcount IS NOT NULL AND @expected_rowcount=@num_rows)
  18305.     BEGIN
  18306.         -- Fast checking was actually used.
  18307.         SET @full_or_fast = 1
  18308.         GOTO ROWCOUNT_MSG
  18309.     END
  18310.  
  18311.  
  18312. -- If we're still here we are doing full row checking at a minimum, and will need the temp table
  18313.  
  18314. IF (SELECT ISNULL(OBJECT_ID('tempdb..#tab_validt1'),0)) = 0    -- Table Does Not exist
  18315.     CREATE TABLE #tab_validt1 (tmp_rows bigint NULL, tmp_checksum numeric NULL)
  18316. ELSE -- table already exists 
  18317.     TRUNCATE TABLE #tab_validt1
  18318.  
  18319. -- If we are only doing row checking, we'll do it here.  If we will do both row checking 
  18320. -- and checksum, then do them together so as to not scan table twice.
  18321.  
  18322.  
  18323. if @rowcount_only = 1
  18324.     BEGIN   -- Must do full count(*) checking but not checksums
  18325.     
  18326.     if @full_or_fast=2   
  18327.         -- if we are here with conditional check (2) requested, it is because
  18328.         -- a conditional was possible, but it failed.  We wiil later alert user of this.
  18329.         BEGIN 
  18330.         SET @full_or_fast=0
  18331.         SET @failed_fast=1
  18332.         END
  18333.  
  18334.     insert into #tab_validt1 (tmp_rows,tmp_checksum) 
  18335.         exec ('select count_big(*), NULL from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  18336.  
  18337.     -- Get row count value
  18338.     select  TOP 1 @num_rows = tmp_rows from #tab_validt1   -- Should only be one row
  18339.         
  18340.     -- IF there were no rows from above, the table was empty so use ZERO.
  18341.     IF @num_rows IS NULL
  18342.         SELECT @num_rows=0
  18343.  
  18344.     -- Done with the temp table
  18345.     DROP TABLE #tab_validt1
  18346.     
  18347.     IF @expected_rowcount IS NULL
  18348.         BEGIN
  18349.         SET @expected_rowcount = @num_rows
  18350.         END
  18351.     GOTO ROWCOUNT_MSG
  18352.     END -- Done with full row count only
  18353.  
  18354. ELSE  -- Doing checksums in addition to ROWCOUNT
  18355.  
  18356.     BEGIN    -- DO checksum and rowcount in same pass thru the table
  18357.     -- Decide whether must use the 7.0 compatible checksum, or use the Shiloh checksum:
  18358.     
  18359.     IF (@rowcount_only = 0)   -- 7.0 Compatible Checksum
  18360.         BEGIN
  18361.         insert into #tab_validt1 (tmp_rows,tmp_checksum)
  18362.             exec ('select count_big(*), sum (convert(numeric, getchecksum(NULL,1))) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  18363.         END
  18364.     ELSE
  18365.     
  18366.         BEGIN  -- Shiloh Checksum
  18367.         
  18368.         
  18369.         if @column_list IS NULL OR @column_list = ' * '
  18370.             begin
  18371.                 insert into #tab_validt1 (tmp_rows,tmp_checksum)
  18372.                     exec ('select count_big(*), sum (convert(numeric, binary_checksum(*) ) ) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  18373.             end
  18374.         else
  18375.             begin
  18376.                 insert into #tab_validt1 (tmp_rows,tmp_checksum)
  18377.                     exec ('select count_big(*), sum (convert(numeric, binary_checksum( ' + @column_list + ') ) ) from ' +    @qualified_table_name + ' (TABLOCK HOLDLOCK)')
  18378.             
  18379.             end            
  18380.         
  18381.         
  18382.         END
  18383.     -- Get the checksum & rowcount values
  18384.     select TOP 1 @checksum = tmp_checksum, @num_rows= tmp_rows from #tab_validt1
  18385.     
  18386.     -- IF there were no rows from above, the table was empty so use ZERO.
  18387.     IF @checksum IS NULL or @num_rows IS NULL
  18388.         SELECT @checksum=isnull(@checksum,0),@num_rows=isnull(@checksum,0)
  18389.  
  18390.     -- Done with the temp table
  18391.     DROP TABLE #tab_validt1
  18392.     
  18393.     IF @expected_rowcount IS NULL  -- Just getting value - no expected value yet.
  18394.         SET @expected_rowcount = @num_rows
  18395.     
  18396.     -- Validate checksum
  18397.     IF @expected_checksum is null        -- Just getting value - no expected value yet.
  18398.         set @expected_checksum = @checksum
  18399.     else
  18400.         -- Raise error if checksums OR rowcounts do not match
  18401.         if @checksum <> @expected_checksum OR @num_rows <> @expected_rowcount
  18402.             begin
  18403.             -- Checksum failed.
  18404.             SELECT     @checksum_string = convert(varchar(21), @checksum),
  18405.                 @expected_checksum_string = convert(varchar(21), @expected_checksum),
  18406.                 @rowcount_string = convert(varchar(21),@num_rows),
  18407.                 @exp_rowcount_string = convert(varchar(21),@expected_rowcount)
  18408.  
  18409.             -- Msg (20525,10,0,'Table ''%s'' might be out of synchronization. Rowcounts (actual: %s, expected %s). Checksum values (actual: %s, expected: %s).', 1033)
  18410.             raiserror (20525, 10, -1, @table, @rowcount_string, @exp_rowcount_string, @checksum_string, @expected_checksum_string)
  18411.             SET @retstatus=1
  18412.             END
  18413.         else
  18414.         BEGIN
  18415.         -- Row count and checksum validation passed.
  18416.         -- 
  18417.         if @asked_for_exp_checksum=0 -- Only give message if not generating the expected value
  18418.             BEGIN
  18419.             -- Msg (20527,10,0,'Table ''%s'' passed rowcount (%s) and checksum validation. (Note: checksum is not compared for any text and image columns.)', 1033)
  18420.             SET @rowcount_string=convert(varchar(21),@num_rows)
  18421.             raiserror (20527, 10, -1, @table,@rowcount_string)
  18422.             END
  18423.         END
  18424.     -- Done with checksum and rowcount scan.
  18425.     END
  18426. -- We did checksum method, and so are done and skip over the rowcount only messages.
  18427.  
  18428. GOTO ALL_DONE
  18429.  
  18430. ROWCOUNT_MSG:
  18431. -- Raise error if rows counts do not match
  18432.     IF @expected_rowcount IS NULL  -- just return the found value
  18433.         SET @expected_rowcount=@num_rows
  18434.     ELSE
  18435.         IF @num_rows <> @expected_rowcount
  18436.         begin
  18437.             SELECT     @rowcount_string=convert(varchar(21),@num_rows),
  18438.                 @exp_rowcount_string=convert(varchar(21),@expected_rowcount)
  18439.             -- Msg (20524,10,0,'Table ''%s'' may be out of synchronization. Rowcounts (actual: %s, expected: %s). Rowcount method %d used (0 = Full, 1 = Fast).', 1033)
  18440.             raiserror (20524, 10, -1, @table_name, @rowcount_string, @exp_rowcount_string, @full_or_fast )
  18441.             SET @retstatus=1
  18442.         end
  18443.         ELSE    -- Row count validation passed. 
  18444.         begin
  18445.             SET @rowcount_string=convert(varchar(21),@num_rows)
  18446.             if @asked_for_exp_rows=0 -- Only give message if not generating the expected value
  18447.                   -- Msg (20526,10,0,'Table ''%s'' passed rowcount (%s) validation. Rowcount method %d used (0 = Full, 1 = Fast).', 1033)
  18448.  
  18449.                 raiserror (20526, 10, -1, @table_name, @rowcount_string, @full_or_fast)
  18450.             
  18451.             if @failed_fast=1
  18452.             BEGIN
  18453.             -- if we had to revert to FULL on a CONDITIONAL FAST, Make that known too.
  18454.             -- And Update usage to fix the problem
  18455.             -- Msg 20558: 'Table ''%s'' passed full row count validation after failing the fast check.  DBCC UPDATEUSAGE will be automatically initiated.'
  18456.             raiserror (20558, 10, -1, @table_name)
  18457.             DBCC UPDATEUSAGE (0,@qualified_table_name,@min_indid) WITH COUNT_ROWS, NO_INFOMSGS
  18458.             END
  18459.         end
  18460.  
  18461. ALL_DONE:
  18462.  
  18463. -- Give nice message if only generating the expected value:
  18464.  
  18465. -- Msg for rows and checksum:
  18466. -- TEMPORARY:   Remove rowcount string & change message if/when RAISERROR can handle bigint directly.
  18467.  
  18468. SET @rowcount_string = convert(varchar(21),@expected_rowcount)
  18469. if @asked_for_exp_checksum=1 and @asked_for_exp_rows=1 -- Only give message if generating the expected value
  18470.        BEGIN
  18471.     
  18472.        SET @expected_checksum_string = convert(varchar(21), @expected_checksum)
  18473.        -- (20579,10,0,'Generated expected rowcount value of %s and expected checksum value of %s for %s.', 1033)
  18474.     RAISERROR (20579, 10, -1,@rowcount_string,@expected_checksum_string,@table_name)
  18475.        END
  18476.        
  18477. ELSE
  18478.     BEGIN
  18479.         if @asked_for_exp_checksum=0 and @asked_for_exp_rows=1
  18480.         -- Msg (20561,10,0,'Generated expected rowcount value of %s for %s.', 1033)
  18481.         raiserror (20561, 10, -1,@rowcount_string, @table_name)
  18482.     END
  18483.  
  18484.  
  18485. -- Raise error that will shutdown replication agents
  18486. if @shutdown_agent = 1
  18487.     --Msg 20578: 'Shutdown replication agent request.'
  18488.     raiserror (20578, 10, -1)
  18489.     
  18490. return @retstatus
  18491. go
  18492.  
  18493. exec dbo.sp_MS_marksystemobject sp_table_validation
  18494. go
  18495.  
  18496. /* Create  sp_removedbreplication */
  18497. raiserror('Creating procedure sp_removedbreplication', 0,1)
  18498. GO
  18499.  
  18500. /* Permission to sysadmin */
  18501. CREATE PROCEDURE sp_removedbreplication (
  18502.       @dbname     sysname
  18503.     ) AS
  18504.  
  18505.     SET NOCOUNT ON
  18506.  
  18507.     /*
  18508.     ** Declarations.
  18509.     */
  18510.  
  18511.     DECLARE @retcode int
  18512.     DECLARE @proc nvarchar(255)
  18513.     DECLARE @optbit int
  18514.     DECLARE @restoreoverride int
  18515.     /*
  18516.     ** Initialization
  18517.     */
  18518.  
  18519.  
  18520.     /*
  18521.     ** Support override of replication remove on attach and restore
  18522.     */
  18523.  
  18524.     declare @instance sysname
  18525.     declare @regkey nvarchar(260)
  18526.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  18527.     select @regkey = 'SOFTWARE\Microsoft\'
  18528.     -- default installation
  18529.     if @instance is null
  18530.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  18531.     else
  18532.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  18533.  
  18534.     SELECT @restoreoverride = 0 -- assume normal remove behavior
  18535.     SELECT @proc = 'master.dbo.xp_regread '
  18536.     EXECUTE @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  18537.                                 @regkey,
  18538.                                 'RestoreOverride',
  18539.                                 @param = @restoreoverride OUTPUT,
  18540.                                 @no_output = 'no_output'
  18541.  
  18542.     IF ( @@error = 0 ) and ( @retcode = 0 )
  18543.     BEGIN
  18544.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  18545.         IF ( ISNULL( @restoreoverride, 0 ) = 1 )
  18546.             RETURN(0)
  18547.     END
  18548.  
  18549.     /*
  18550.     ** Parameter check
  18551.     ** @dbname
  18552.     */
  18553.     IF NOT EXISTS (SELECT * FROM master.dbo.sysdatabases WHERE
  18554.         name = @dbname collate database_default)
  18555.     BEGIN
  18556.         RAISERROR(15010, 16, -1, @dbname)
  18557.         RETURN(1)
  18558.     END
  18559.  
  18560.     
  18561.     SELECT @proc = quotename(@dbname) + '.dbo.sp_MSremovedbreplication'
  18562.     
  18563.     EXEC @retcode = @proc 
  18564.     IF @@ERROR <> 0 or @retcode <> 0
  18565.     BEGIN
  18566.         return (1)
  18567.     END
  18568.  
  18569.     -- Clear tran bit
  18570.     SELECT @optbit = 1
  18571.     IF EXISTS (SELECT * FROM master..sysdatabases
  18572.         WHERE name = @dbname collate database_default
  18573.         AND (category & @optbit) <> 0)
  18574.     begin
  18575.         /*
  18576.         ** Toggle the category bit in master..sysdatabases
  18577.         */
  18578.         UPDATE master..sysdatabases SET category = category & ~@optbit
  18579.                 WHERE name = @dbname collate database_default
  18580.         IF @@ERROR <> 0 
  18581.         BEGIN
  18582.             return (1)
  18583.         END
  18584.     end
  18585.  
  18586.     -- Clear merge bit
  18587.     SELECT @optbit = 4
  18588.     IF EXISTS (SELECT * FROM master..sysdatabases
  18589.         WHERE name = @dbname collate database_default
  18590.         AND (category & @optbit) <> 0)
  18591.     begin
  18592.         /*
  18593.         ** Toggle the category bit in master..sysdatabases
  18594.         */
  18595.         UPDATE master..sysdatabases SET category = category & ~@optbit
  18596.                 WHERE name = @dbname collate database_default
  18597.         IF @@ERROR <> 0 
  18598.         BEGIN
  18599.             return (1)
  18600.         END
  18601.     end
  18602.  
  18603. GO
  18604.  
  18605. exec dbo.sp_MS_marksystemobject sp_removedbreplication
  18606. go
  18607.  
  18608. raiserror('Creating procedure sp_removesrvreplication', 0,1)
  18609. GO
  18610.  
  18611. create procedure sp_removesrvreplication
  18612. as
  18613. begin
  18614. /* 
  18615.  * unmark replication bits for all servers, databases; used by setup in vupgrade 
  18616.  * assumes override is on; db in single user mode
  18617.  * no need to check rowcounts affected by updates, may not be any repl dbs
  18618.  * failure label avoids repetition of errs if not in single user mode
  18619. */
  18620.  
  18621.     set nocount on 
  18622.  
  18623.     -- server bits
  18624.     declare @srv_distbit int
  18625.     declare @srv_pubbit int
  18626.     declare @srv_subbit int
  18627.     declare @srv_dsnbit int
  18628.  
  18629.     select @srv_distbit = 8, @srv_pubbit = 16, @srv_subbit = 4, @srv_dsnbit = 32 -- dsn subscriber
  18630.  
  18631.     -- db bits
  18632.     declare @db_tranbit int
  18633.     declare @db_mergbit int
  18634.     declare @db_distbit int
  18635.  
  18636.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  18637.  
  18638.     -- setup attach overrides removedb option
  18639.     declare @dbname sysname
  18640.  
  18641.     declare cur_db CURSOR LOCAL FAST_FORWARD for 
  18642.         select name from master..sysdatabases where name <> N'master' collate database_default
  18643.         for read only
  18644.     open cur_db
  18645.     fetch cur_db into @dbname
  18646.     while ( @@fetch_status <> -1 )
  18647.     begin
  18648.         exec dbo.sp_removedbreplication @dbname
  18649.         -- clean up system tables
  18650.         exec ( @dbname + '.dbo.sp_MSdrop_pub_tables' )
  18651.         exec ( @dbname + '.dbo.sp_MSdrop_mergesystables' )
  18652.         fetch next from cur_db into @dbname
  18653.     end
  18654.     close cur_db
  18655.     deallocate cur_db
  18656.  
  18657.     -- unmark db bits
  18658.     -- select name, category from sysdatabases where category & @tranbit = @tranbit 
  18659.     update master..sysdatabases set category = category & ~@db_tranbit where category & @db_tranbit = @db_tranbit
  18660.     if @@ERROR <> 0
  18661.         goto fail
  18662.  
  18663.     update master..sysdatabases set category = category & ~@db_mergbit where category & @db_mergbit = @db_mergbit
  18664.     if @@ERROR <> 0
  18665.         goto fail
  18666.  
  18667.     -- clean up old dist db bit
  18668.     update master..sysdatabases set category = category & ~@db_distbit where category & @db_distbit = @db_distbit
  18669.     if @@ERROR <> 0
  18670.         goto fail
  18671.  
  18672.     -- unmark srv bits (srvstatus = @dsnbit no longer used by replication subscribers but by server )
  18673.     -- select name, srvstatus from sysservers where srvstatus & @srv_distbit = @srv_distbit
  18674.     update master..sysservers set srvstatus = srvstatus & ~@srv_subbit where srvstatus & @srv_subbit = @srv_subbit
  18675.     if @@ERROR <> 0
  18676.         goto fail
  18677.  
  18678.     update master..sysservers set srvstatus = srvstatus & ~@srv_pubbit where srvstatus & @srv_pubbit = @srv_pubbit
  18679.     if @@ERROR <> 0
  18680.         goto fail
  18681.  
  18682.     update master..sysservers set srvstatus = srvstatus & ~@srv_distbit where srvstatus & @srv_distbit = @srv_distbit
  18683.     if @@ERROR <> 0
  18684.         goto fail
  18685.  
  18686.     return (0)
  18687.  
  18688. fail:
  18689. -- ad hoc updates not allowed and not single user
  18690. return (1)
  18691.  
  18692. end
  18693. go
  18694.  
  18695. exec dbo.sp_MS_marksystemobject sp_removesrvreplication
  18696. go
  18697.  
  18698. raiserror('Creating procedure sp_MSremovedbreplication', 0,1)
  18699. GO
  18700.  
  18701. CREATE PROCEDURE sp_MSremovedbreplication
  18702.     AS
  18703.  
  18704.     SET NOCOUNT ON
  18705.  
  18706.     /*
  18707.     ** Declarations.
  18708.     */
  18709.  
  18710.     DECLARE @retcode int
  18711.  
  18712.     -- If the attach info table exists, we need to restore the subscriptions, not
  18713.     -- deleting anything. Do nothing.
  18714.     if exists (select * from sysobjects where
  18715.         name = 'MSreplication_restore_stage')
  18716.         return 0
  18717.  
  18718.     if exists (select * from sysobjects where name = 'sysarticles')
  18719.     -- clean up transactional 
  18720.     begin
  18721.         if not exists (select * from master..MSreplication_options
  18722.             where optname = 'transactional')
  18723.         begin
  18724.             RAISERROR(21027, 16, -1, 'transactional')
  18725.             return(1)
  18726.         end
  18727.     
  18728.         
  18729.         EXEC @retcode = dbo.sp_MSpublishdb @value = 'false',
  18730.             @ignore_distributor = 1
  18731.         IF @@ERROR <> 0 or @retcode <> 0
  18732.         BEGIN
  18733.             return (1)
  18734.         END
  18735.     end
  18736.  
  18737.     if exists (select * from sysobjects where name = 'sysmergearticles')
  18738.     -- clean up merge
  18739.     -- can not use sp_MSmergepublishdb or sp_dropmergepullsubscriptions
  18740.     -- since they depend on serverid and dbname
  18741.     begin
  18742.         declare @pubid uniqueidentifier
  18743.         declare @artid uniqueidentifier
  18744.         declare hC CURSOR LOCAL FAST_FORWARD FOR select DISTINCT pubid, artid FROM 
  18745.             sysmergearticles
  18746.         FOR READ ONLY       
  18747.  
  18748.         OPEN hC
  18749.         FETCH hC INTO @pubid, @artid
  18750.         WHILE (@@fetch_status <> -1)
  18751.         begin
  18752.  
  18753.             EXEC @retcode = dbo.sp_MSarticlecleanup
  18754.                 @pubid, @artid
  18755.             IF @@ERROR <> 0 or @retcode <> 0
  18756.             BEGIN
  18757.                 return (1)
  18758.             end
  18759.             FETCH hC INTO @pubid, @artid
  18760.         end
  18761.  
  18762.         execute @retcode = dbo.sp_MSdrop_mergesystables
  18763.         if @@ERROR <> 0 or @retcode <> 0
  18764.         begin
  18765.                 return (1)
  18766.         end
  18767.     end
  18768.  
  18769.  
  18770.     if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  18771.     -- clean up tran sub
  18772.     begin
  18773.         -- drop pull subscription
  18774.         EXEC @retcode = dbo.sp_droppullsubscription
  18775.             @publisher = N'all', 
  18776.             @publisher_db = N'all', 
  18777.             @publication = N'all'
  18778.         IF @@ERROR <> 0 or @retcode <> 0
  18779.         BEGIN
  18780.             return (1)
  18781.         END
  18782.  
  18783.         -- drop push subscription
  18784.         EXEC @retcode = dbo.sp_subscription_cleanup
  18785.             @publisher = N'all', 
  18786.             @publisher_db = N'all', 
  18787.             @publication = N'all',
  18788.             @reserved = 'drop_all'
  18789.         IF @@ERROR <> 0 or @retcode <> 0
  18790.         BEGIN
  18791.             return (1)
  18792.         END
  18793.     end
  18794.     
  18795. GO
  18796.  
  18797. exec dbo.sp_MS_marksystemobject sp_MSremovedbreplication
  18798. go
  18799.  
  18800. raiserror('Creating procedure sp_vupgrade_subscription_databases', 0,1)
  18801. GO
  18802. create procedure sp_vupgrade_subscription_databases
  18803. as
  18804. begin
  18805. /* 
  18806.  * Process schema and metadata changes common to all databases. This proc loops
  18807.  * through each database and upgrades MSsubscription_properties, transactional tables
  18808.  * and merge tables.
  18809.  *
  18810.  * Setup version upgrade procedure call order:
  18811.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases
  18812. */
  18813.     set nocount on
  18814.  
  18815.     -- raiserror('sp_vupgrade_subscription_databases', 0,1) with nowait
  18816.     declare @dbname nvarchar(270), @has_dbaccess bit
  18817.  
  18818.     declare current_db CURSOR LOCAL FAST_FORWARD for 
  18819.         select N'[' + replace(name, N']', N']]') + N']', has_dbaccess(name) from master..sysdatabases 
  18820.             WHERE name <> N'master' collate database_default
  18821.             AND name <> N'tempdb' collate database_default
  18822.             AND name <> N'msdb' collate database_default
  18823.         for read only
  18824.  
  18825.     -- Note: dbname is quoted!
  18826.     open current_db
  18827.     fetch current_db into @dbname, @has_dbaccess
  18828.     while ( @@fetch_status <> -1 )
  18829.     begin
  18830.  
  18831.         -- upgrade repl tables in sub dbs if needed - sub dbs are not marked with subscribed status 
  18832.         -- skip any database in an offline state and write warning to upgrade log
  18833.         if ( @has_dbaccess = 1 )
  18834.         begin
  18835.             --
  18836.             -- NOTE : there are several things to process here
  18837.             -- for each upgrade - all these steps may NOT be necessary
  18838.             -- and should be commented/uncommented out as required
  18839.             -- 
  18840.             -- Current setting for SQL 2000 SP1 upgrade
  18841.             --
  18842.             raiserror( 21377, 0, 1, @dbname) with nowait
  18843.             -- exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_MSsubscription_properties')
  18844.             exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subscription_tables')
  18845.             exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_mergetables')
  18846.             -- exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_subpass')
  18847.         end
  18848.         else
  18849.         begin
  18850.             raiserror( 21373, 10, 1, @dbname) with nowait
  18851.         end
  18852.  
  18853.         fetch next from current_db into @dbname, @has_dbaccess
  18854.     end
  18855.     close current_db
  18856.     deallocate current_db
  18857. end
  18858. go
  18859.  
  18860. raiserror('Creating procedure sp_MScopyregvalue', 0,1)
  18861. GO
  18862. create procedure sp_MScopyregvalue(    
  18863.     @oldregkey            nvarchar(1000),
  18864.     @newregkey            nvarchar(1000),
  18865.     @param_type            nvarchar(20),
  18866.     @param_name            sysname)
  18867. as
  18868.     set nocount on
  18869.     declare @retcode     int
  18870.     create table #binaryvalues ( value sysname collate database_default, data varbinary(256))
  18871.     if (@param_type = 'REG_SZ')
  18872.         begin
  18873.             declare @value_str nvarchar(1000)
  18874.             set @value_str = NULL
  18875.             -- Read value from old reg location and write to new one
  18876.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  18877.                                    @oldregkey,
  18878.                                    @param_name,
  18879.                                    @param = @value_str OUTPUT,
  18880.                                    @no_output = 'no_output'
  18881.             if @retcode <> 0 or @@ERROR <> 0
  18882.                 begin
  18883.                     set @retcode = 0
  18884.                     goto FAILURE
  18885.                 end                
  18886.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  18887.                                @newregkey,
  18888.                                @param_name,
  18889.                             'REG_SZ',
  18890.                                @value_str
  18891.             if @retcode <> 0 OR @@ERROR <> 0
  18892.             begin
  18893.                 set @retcode = 1
  18894.                 goto FAILURE
  18895.             end                
  18896.         end
  18897.     if (@param_type = 'REG_DWORD')
  18898.         begin
  18899.             declare @value_int int
  18900.             set @value_int = NULL
  18901.             -- Read value from old reg location and write to new one
  18902.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  18903.                                    @oldregkey,
  18904.                                    @param_name,
  18905.                                    @param = @value_int OUTPUT,
  18906.                                    @no_output = 'no_output'
  18907.             if @retcode <> 0 or @@ERROR <> 0
  18908.                 begin
  18909.                     set @retcode = 0
  18910.                     goto FAILURE
  18911.                 end                
  18912.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  18913.                                @newregkey,
  18914.                                @param_name,
  18915.                             'REG_DWORD',
  18916.                                @value_int
  18917.             if @retcode <> 0 OR @@ERROR <> 0
  18918.             begin
  18919.                 set @retcode = 1
  18920.                 goto FAILURE
  18921.             end
  18922.         end
  18923.     if (@param_type = 'REG_BINARY')
  18924.         begin
  18925.             declare @value_binary varbinary(256)
  18926.             set @value_binary = NULL
  18927.             -- Read value from old reg location and write to new one
  18928. /*
  18929.     -- binary output buffer was corrupted for a couple of builds;looks to be working now
  18930.     -- if reverting to this read, must pre-check exists on regkey to avoid regopenkey failure 
  18931.     -- on non-existent key when no OUTPUT parm specified
  18932.             insert into #binaryvalues EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  18933.                                    @oldregkey,
  18934.                                    @param_name
  18935.             if @@ERROR <> 0
  18936.                 begin
  18937.                     set @retcode = 0
  18938.                     goto FAILURE
  18939.                 end        
  18940.             select @value_binary = data from #binaryvalues
  18941.             if @value_binary is NOT NULL
  18942.                 EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  18943.                                    @newregkey,
  18944.                                    @param_name,
  18945.                                 'REG_BINARY',
  18946.                                    @value_binary
  18947.                                    
  18948. */
  18949.             EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE',
  18950.                                    @oldregkey,
  18951.                                    @param_name,
  18952.                                    @param = @value_binary OUTPUT,
  18953.                                    @no_output = 'no_output'
  18954.             if @retcode <> 0 or @@ERROR <> 0
  18955.                 begin
  18956.                     set @retcode = 0
  18957.                     goto FAILURE
  18958.                 end                
  18959.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  18960.                                @newregkey,
  18961.                                @param_name,
  18962.                             'REG_BINARY',
  18963.                                @value_binary
  18964.             if @retcode <> 0 OR @@ERROR <> 0
  18965.                 begin
  18966.                     set @retcode = 1
  18967.                     goto FAILURE
  18968.                 end
  18969.         end
  18970.     set @retcode = 0
  18971. FAILURE:
  18972.     drop table #binaryvalues
  18973.     return @retcode
  18974. go
  18975.  
  18976. raiserror('Creating procedure sp_vupgrade_registry', 0,1)
  18977. GO
  18978. create procedure sp_vupgrade_registry
  18979. as
  18980.     set nocount on
  18981.     declare @oldregkey                        nvarchar(1000)
  18982.     declare @newregkey                        nvarchar(1000)
  18983.     declare @subscription_name                nvarchar(1000)
  18984.     declare @resolver_name                    nvarchar(1000)
  18985.     declare @resolver_clsid                    nvarchar(1000)
  18986.     declare @retcode                        int
  18987.     declare @keyexist                         int
  18988.     
  18989.     -- raiserror('sp_vupgrade_registry', 0,1)
  18990.     
  18991.     create table #keyexist (keyexist int)
  18992.  
  18993.     set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  18994.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  18995.     select @keyexist = keyexist from #keyexist
  18996.  
  18997.     if @keyexist = 1
  18998.     begin
  18999.         -- Move the registered subscriptions to new location in registry
  19000.         create table #syncmgr_subscriptions (subscription_name nvarchar(1000) collate database_default)
  19001.         set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  19002.         insert into #syncmgr_subscriptions EXECUTE master.dbo.xp_regenumkeys 'HKEY_LOCAL_MACHINE', @oldregkey
  19003.         declare #subscriptioncursor CURSOR LOCAL FAST_FORWARD FOR 
  19004.             select DISTINCT subscription_name
  19005.                    FROM #syncmgr_subscriptions    FOR READ ONLY
  19006.  
  19007.         open #subscriptioncursor
  19008.         fetch next from #subscriptioncursor into @subscription_name
  19009.         while (@@fetch_status <> -1)
  19010.         begin
  19011.  
  19012.             set @newregkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  19013.             set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\' + @subscription_name
  19014.  
  19015.             delete from #keyexist
  19016.             insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  19017.             select @keyexist = keyexist from #keyexist
  19018.             if @keyexist = 1
  19019.                 begin
  19020.  
  19021.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'ProfileName'        
  19022.                     if @retcode <> 0
  19023.                         begin
  19024.                             set @retcode = 1
  19025.                             goto FAILURE
  19026.                         end                
  19027.  
  19028.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'HostName'        
  19029.                     if @retcode <> 0
  19030.                         begin
  19031.                             set @retcode = 1
  19032.                             goto FAILURE
  19033.                         end                
  19034.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'ReplicationType'        
  19035.                     if @retcode <> 0
  19036.                         begin
  19037.                             set @retcode = 1
  19038.                             goto FAILURE
  19039.                         end                
  19040.  
  19041.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriptionType'        
  19042.                     if @retcode <> 0
  19043.                         begin
  19044.                             set @retcode = 1
  19045.                             goto FAILURE
  19046.                         end                
  19047.  
  19048.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'ExchangeType'        
  19049.                     if @retcode <> 0
  19050.                         begin
  19051.                             set @retcode = 1
  19052.                             goto FAILURE
  19053.                         end                
  19054.  
  19055.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'Validate'        
  19056.                     if @retcode <> 0
  19057.                         begin
  19058.                             set @retcode = 1
  19059.                             goto FAILURE
  19060.                         end                
  19061.  
  19062.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'LoginTimeout'        
  19063.                     if @retcode <> 0
  19064.                         begin
  19065.                             set @retcode = 1
  19066.                             goto FAILURE
  19067.                         end                
  19068.  
  19069.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'QueryTimeout'        
  19070.                     if @retcode <> 0
  19071.                         begin
  19072.                             set @retcode = 1
  19073.                             goto FAILURE
  19074.                         end                
  19075.  
  19076.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriptionName'        
  19077.                     if @retcode <> 0
  19078.                         begin
  19079.                             set @retcode = 1
  19080.                             goto FAILURE
  19081.                         end                
  19082.  
  19083.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'LastUpdateTime'        
  19084.                     if @retcode <> 0
  19085.                         begin
  19086.                             set @retcode = 1
  19087.                             goto FAILURE
  19088.                         end                
  19089.  
  19090.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Subid'        
  19091.                     if @retcode <> 0
  19092.                         begin
  19093.                             set @retcode = 1
  19094.                             goto FAILURE
  19095.                         end                
  19096.  
  19097.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Publication'        
  19098.                     if @retcode <> 0
  19099.                         begin
  19100.                             set @retcode = 1
  19101.                             goto FAILURE
  19102.                         end                
  19103.  
  19104.  
  19105.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Publisher'        
  19106.                     if @retcode <> 0
  19107.                         begin
  19108.                             set @retcode = 1
  19109.                             goto FAILURE
  19110.                         end                
  19111.  
  19112.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherDb'        
  19113.                     if @retcode <> 0
  19114.                         begin
  19115.                             set @retcode = 1
  19116.                             goto FAILURE
  19117.                         end                
  19118.  
  19119.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'PublisherSecurityMode'        
  19120.                     if @retcode <> 0
  19121.                         begin
  19122.                             set @retcode = 1
  19123.                             goto FAILURE
  19124.                         end                
  19125.  
  19126.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherLogin'        
  19127.                     if @retcode <> 0
  19128.                         begin
  19129.                             set @retcode = 1
  19130.                             goto FAILURE
  19131.                         end                
  19132.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherEncryptedPassword'        
  19133.                     if @retcode <> 0
  19134.                         begin
  19135.                             set @retcode = 1
  19136.                             goto FAILURE
  19137.                         end                
  19138.  
  19139.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'PublisherEncryptedPasswordBinary'        
  19140.                     if @retcode <> 0
  19141.                         begin
  19142.                             set @retcode = 1
  19143.                             goto FAILURE
  19144.                         end                
  19145.  
  19146.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherAddress'        
  19147.                     if @retcode <> 0
  19148.                         begin
  19149.                             set @retcode = 1
  19150.                             goto FAILURE
  19151.                         end                
  19152.  
  19153.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'PublisherNetwork'        
  19154.                     if @retcode <> 0
  19155.                         begin
  19156.                             set @retcode = 1
  19157.                             goto FAILURE
  19158.                         end    
  19159.  
  19160.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Subscriber'        
  19161.                     if @retcode <> 0
  19162.                         begin
  19163.                             set @retcode = 1
  19164.                             goto FAILURE
  19165.                         end                
  19166.  
  19167.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberDb'        
  19168.                     if @retcode <> 0
  19169.                         begin
  19170.                             set @retcode = 1
  19171.                             goto FAILURE
  19172.                         end                
  19173.  
  19174.  
  19175.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriberSecurityMode'        
  19176.                     if @retcode <> 0
  19177.                         begin
  19178.                             set @retcode = 1
  19179.                             goto FAILURE
  19180.                         end                
  19181.  
  19182.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberLogin'        
  19183.                     if @retcode <> 0
  19184.                         begin
  19185.                             set @retcode = 1
  19186.                             goto FAILURE
  19187.                         end                
  19188.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberEncryptedPassword'        
  19189.                     if @retcode <> 0
  19190.                         begin
  19191.                             set @retcode = 1
  19192.                             goto FAILURE
  19193.                         end                
  19194.  
  19195.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'SubscriberEncryptedPasswordBinary'        
  19196.                     if @retcode <> 0
  19197.                         begin
  19198.                             set @retcode = 1
  19199.                             goto FAILURE
  19200.                         end                
  19201.  
  19202.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'SubscriberDatasourceType'        
  19203.                     if @retcode <> 0
  19204.                         begin
  19205.                             set @retcode = 1
  19206.                             goto FAILURE
  19207.                         end                
  19208.  
  19209.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'SubscriberDatabasePath'        
  19210.                     if @retcode <> 0
  19211.                         begin
  19212.                             set @retcode = 1
  19213.                             goto FAILURE
  19214.                         end                
  19215.  
  19216.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'Distributor'        
  19217.                     if @retcode <> 0
  19218.                         begin
  19219.                             set @retcode = 1
  19220.                             goto FAILURE
  19221.                         end                
  19222.  
  19223.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'DistributorSecurityMode'        
  19224.                     if @retcode <> 0
  19225.                         begin
  19226.                             set @retcode = 1
  19227.                             goto FAILURE
  19228.                         end                
  19229.  
  19230.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorLogin'        
  19231.                     if @retcode <> 0
  19232.                         begin
  19233.                             set @retcode = 1
  19234.                             goto FAILURE
  19235.                         end                
  19236.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorEncryptedPassword'        
  19237.                     if @retcode <> 0
  19238.                         begin
  19239.                             set @retcode = 1
  19240.                             goto FAILURE
  19241.                         end                
  19242.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_BINARY', 'DistributorEncryptedPasswordBinary'        
  19243.                     if @retcode <> 0
  19244.                         begin
  19245.                             set @retcode = 1
  19246.                             goto FAILURE
  19247.                         end                
  19248.  
  19249.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorAddress'        
  19250.                     if @retcode <> 0
  19251.                         begin
  19252.                             set @retcode = 1
  19253.                             goto FAILURE
  19254.                         end                
  19255.  
  19256.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_SZ', 'DistributorNetwork'        
  19257.                     if @retcode <> 0
  19258.                         begin
  19259.                             set @retcode = 1
  19260.                             goto FAILURE
  19261.                         end    
  19262.  
  19263.                     exec @retcode = sp_MScopyregvalue    @oldregkey,    @newregkey,    'REG_DWORD', 'UseInteractiveResolver'        
  19264.                     if @retcode <> 0
  19265.                         begin
  19266.                             set @retcode = 1
  19267.                             goto FAILURE
  19268.                         end    
  19269.  
  19270.                     -- regdelete returns 'Access Denied' message if key does not exist; check before delete
  19271.                     delete from #keyexist
  19272.                     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  19273.                     select @keyexist = keyexist from #keyexist
  19274.                     if @keyexist = 1
  19275.                     begin
  19276.                         exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  19277.                         if @@error <> 0 OR @retcode <> 0
  19278.                         begin
  19279.                             set @retcode = 1
  19280.                             goto FAILURE
  19281.                         end                
  19282.                     end
  19283.                 end
  19284.             fetch next from #subscriptioncursor into @subscription_name
  19285.         end
  19286.  
  19287.         close #subscriptioncursor
  19288.         deallocate #subscriptioncursor
  19289.         drop table #syncmgr_subscriptions 
  19290.  
  19291.         -- done moving reg keys/values.  delete old key; check key exists before delete
  19292.         set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\Subscriptions\'
  19293.         delete from #keyexist
  19294.         insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  19295.         select @keyexist = keyexist from #keyexist
  19296.         if @keyexist = 1
  19297.         begin
  19298.             exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  19299.             if @@error <> 0 OR @retcode <> 0
  19300.             begin
  19301.                 set @retcode = 1
  19302.                 goto FAILURE
  19303.             end
  19304.         end                
  19305.     end            
  19306.  
  19307.     -- Move the registered article resolvers to new location in registry
  19308.     set @oldregkey = 'SOFTWARE\Microsoft\MSSQLServer\Replication\ArticleResolver'
  19309.     set @newregkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\ArticleResolver' 
  19310.     delete from #keyexist
  19311.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @oldregkey
  19312.     select @keyexist = keyexist from #keyexist
  19313.     if @keyexist = 1
  19314.         begin
  19315.  
  19316.             create table #article_resolvers (resolver_name nvarchar(1000) collate database_default, resolver_clsid nvarchar(1000))
  19317.             insert into #article_resolvers EXECUTE master.dbo.xp_regenumvalues 'HKEY_LOCAL_MACHINE', @oldregkey
  19318.             declare #resolvercursor CURSOR LOCAL FAST_FORWARD FOR 
  19319.                 select DISTINCT resolver_name, resolver_clsid
  19320.                        FROM #article_resolvers
  19321.                     FOR READ ONLY
  19322.  
  19323.             open #resolvercursor
  19324.             fetch next from #resolvercursor into @resolver_name, @resolver_clsid
  19325.             while (@@fetch_status <> -1)
  19326.             begin
  19327.                 exec @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE', @newregkey, @resolver_name, 'REG_SZ', @resolver_clsid
  19328.                 if @retcode <> 0 OR @@ERROR <> 0
  19329.                     begin
  19330.                         set @retcode = 1
  19331.                         goto FAILURE
  19332.                     end                
  19333.                 fetch next from #resolvercursor into @resolver_name, @resolver_clsid
  19334.             end
  19335.  
  19336.             -- done moving reg keys/values.  delete old key 
  19337.             exec @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @oldregkey
  19338.             if @@error <> 0 OR @retcode <> 0
  19339.             begin
  19340.                 set @retcode = 1
  19341.                 goto FAILURE
  19342.             end                
  19343.             close #resolvercursor
  19344.             deallocate #resolvercursor
  19345.             drop table #article_resolvers 
  19346.         end
  19347.     set @retcode = 0
  19348. FAILURE:
  19349.     drop table #keyexist
  19350.     return @retcode
  19351.  
  19352. go
  19353. exec dbo.sp_MS_marksystemobject sp_vupgrade_registry
  19354. go
  19355.  
  19356. raiserror('Creating procedure sp_vupgrade_subscription_tables', 0,1)
  19357. GO
  19358. create procedure sp_vupgrade_subscription_tables
  19359. as
  19360. begin
  19361. /* 
  19362.  * Process schema and metadata changes common to transactional pub/sub databases. Exception is creation
  19363.  * of MSrepl_identity_range table needed for tran and merge publishing databases and merge subscr db's.
  19364.  *
  19365.  * Setup version upgrade procedure call order:
  19366.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_subscription_tables
  19367. */
  19368.  
  19369.     -- raiserror('sp_vupgrade_subscription_tables', 0,1) with nowait
  19370.  
  19371.     set nocount on 
  19372.  
  19373.     DECLARE @table_name sysname
  19374.     declare @retcode int
  19375.  
  19376.     -- Identity range management; create in  publishing databases
  19377.     if exists (select * from sysobjects where name = 'sysarticles')
  19378.     begin
  19379.         if not exists (select * from sysobjects where name = 'MSpub_identity_range')
  19380.         begin        
  19381.             CREATE TABLE dbo.MSpub_identity_range
  19382.             (
  19383.                 objid int not null,
  19384.                 range bigint not null,
  19385.                 pub_range bigint not null,
  19386.                 current_pub_range bigint not null,
  19387.                 threshold int not null,
  19388.                 last_seed bigint null -- It will be not when uninitialized.
  19389.             )     
  19390.  
  19391.             IF @@ERROR <> 0
  19392.             BEGIN
  19393.                 return(1)
  19394.             END
  19395.  
  19396.             -- mark the index as a system object
  19397.             exec dbo.sp_MS_marksystemobject 'MSpub_identity_range'
  19398.  
  19399.             IF @@ERROR <> 0
  19400.             BEGIN
  19401.                 return(1)
  19402.             END
  19403.  
  19404.             create unique nonclustered index unc1MSpub_identity_range
  19405.                 on MSpub_identity_range (objid)
  19406.  
  19407.             IF @@ERROR <> 0
  19408.             BEGIN
  19409.                 return(1)
  19410.             END
  19411.         end
  19412.     end
  19413.  
  19414.     -- Identity range management; create in all publishing databases and merge subscription databases (Shiloh)
  19415.     if exists (select * from sysobjects where name = 'sysmergearticles')
  19416.     begin
  19417.         if not exists (select * from sysobjects where name = 'MSrepl_identity_range')
  19418.         begin        
  19419.             create table dbo.MSrepl_identity_range (
  19420.                 objid                    int not NULL primary key,
  19421.                 next_seed                bigint NULL, --resource control
  19422.                 pub_range                bigint NULL, --publisher range
  19423.                 range                    bigint NULL, -- set by sp_addmergearticle
  19424.                 max_identity            bigint NULL, --resource control
  19425.                 threshold                int    NULL,    --in percentage, set by sp_addmergearticle
  19426.                 current_max                bigint NULL    --max value for current check constraint,set by sp_addmergearticle
  19427.                 )
  19428.             exec dbo.sp_MS_marksystemobject MSrepl_identity_range
  19429.             if @@ERROR <> 0
  19430.                 return(1)
  19431.             grant select on MSrepl_identity_range to public
  19432.         end
  19433.     end
  19434.  
  19435.     --    Create unique index on tables that did not have one previously. The index is not created
  19436.     --    if duplicates rows exist in the table. 
  19437.  
  19438.     --    MSreplication_subscriptions (SQL7.0 SP1)
  19439.     SELECT @table_name = N'MSreplication_subscriptions'
  19440.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_subscriptions' ) or 
  19441.         EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSsubscription_agents' )
  19442.     BEGIN
  19443.         IF EXISTS ( SELECT publication, publisher_db, publisher, subscription_type 
  19444.             FROM MSreplication_subscriptions
  19445.             GROUP BY publication, publisher_db, publisher, subscription_type
  19446.             HAVING COUNT(*) > 1 )
  19447.             RAISERROR (21203, 10, 1, @table_name)
  19448.         ELSE
  19449.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'uc1MSReplication_subscriptions' AND
  19450.                 id = OBJECT_ID('MSreplication_subscriptions') )
  19451.                 CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  19452.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  19453.         
  19454.         -- Create MSsubscription_agents table 
  19455.         exec @retcode = dbo.sp_MScreate_sub_tables
  19456.             @tran_sub_table = 1,
  19457.             @property_table = 0,
  19458.             @sqlqueue_table = 0
  19459.         IF @@ERROR <> 0 or @retcode <> 0
  19460.             RETURN(1)
  19461.  
  19462.         -- Add new columns to MSsubscription_agents, for 8.0 pre beta upgrade.
  19463.  
  19464.         -- status of the last sync (Shiloh)
  19465.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  19466.                             name = 'last_sync_status')
  19467.         begin
  19468.                 alter table MSsubscription_agents add last_sync_status int NULL
  19469.                 if @@ERROR <> 0
  19470.                     return 1
  19471.         end
  19472.  
  19473.         -- summary message of the last sync (Shiloh)
  19474.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  19475.                             name = 'last_sync_summary')
  19476.         begin
  19477.                 alter table MSsubscription_agents add last_sync_summary sysname NULL
  19478.                 if @@ERROR <> 0
  19479.                     return 1
  19480.         end
  19481.  
  19482.         -- summary message of the last sync (Shiloh)
  19483.         if not exists (select * from syscolumns where id = object_id('MSsubscription_agents') and
  19484.                             name = 'last_sync_time')
  19485.         begin
  19486.                 alter table MSsubscription_agents add last_sync_time datetime NULL
  19487.                 if @@ERROR <> 0
  19488.                     return 1
  19489.         end
  19490.     END
  19491.  
  19492.     --    MSreplication_objects (SQL7.0 SP1)
  19493.     SELECT @table_name = N'MSreplication_objects'
  19494.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSreplication_objects' ) 
  19495.     BEGIN
  19496.         IF EXISTS ( SELECT object_name
  19497.             FROM MSreplication_objects
  19498.             GROUP BY object_name
  19499.             HAVING COUNT(*) > 1 )
  19500.             RAISERROR (21203, 10, 3, @table_name)
  19501.         ELSE    
  19502.             IF NOT EXISTS ( SELECT * FROM sysindexes WHERE name = 'ucMSreplication_objects' AND
  19503.                 id = OBJECT_ID('MSreplication_objects') )
  19504.                 CREATE UNIQUE CLUSTERED INDEX ucMSreplication_objects ON dbo.MSreplication_objects(object_name)
  19505.     END
  19506.  
  19507. end
  19508. go
  19509.  
  19510. exec dbo.sp_MS_marksystemobject sp_vupgrade_subscription_tables
  19511. go
  19512.  
  19513. raiserror('Creating procedure sp_vupgrade_mergetables', 0,1)
  19514. GO
  19515. create procedure sp_vupgrade_mergetables( @skip_procgen bit = 0 )
  19516. as
  19517. begin
  19518. /* 
  19519.  * Process schema and metadata changes common to transactional pub/sub databases.
  19520.  *
  19521.  * @skip_procgen is set by sp_restoredbreplication when calling this proc directly to update
  19522.  * system tables during restore of a down-level (e.g. - SQL7.0) database to current version
  19523.  * 
  19524.  * Setup version upgrade procedure call order:
  19525.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_mergetables
  19526. */
  19527.  
  19528.     set nocount on 
  19529.  
  19530.     declare @artnick int
  19531.     declare @objid  int
  19532.     declare @col_track int
  19533.     declare @article sysname
  19534.     declare @pubname sysname
  19535.     declare @artid uniqueidentifier
  19536.     declare @pubid uniqueidentifier
  19537.     declare @qualified_name         nvarchar(257)
  19538.     declare @source_owner           sysname
  19539.     declare @source_object            sysname
  19540.     declare @table_name                sysname
  19541.     declare @retcode                integer
  19542.     declare @snapshot_ready            int
  19543.     declare @cmd                     nvarchar(4000)
  19544.  
  19545.     -- raiserror('sp_vupgrade_mergetables', 0,1)
  19546.  
  19547.     /*
  19548.      * sysmergearticles
  19549.     */
  19550.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  19551.     begin
  19552.  
  19553.         -- Set all invalid sysmergearticles.sync_objid to the corresponding 
  19554.         -- objid, this will allow regeneration of article procs to succeed
  19555.         update dbo.sysmergearticles 
  19556.            set sync_objid = objid 
  19557.          where object_name(sync_objid) is null
  19558.  
  19559.         if @@ERROR<>0
  19560.             return(1)
  19561.  
  19562.         exec @retcode = dbo.sp_MSUpgradeConflictTable @skip_procgen
  19563.         if @@ERROR<>0 or @retcode<>0
  19564.             return (1)        
  19565.         if not exists (select * from syscolumns where id = object_id('sysmergearticles') and
  19566.                         name = 'maxversion_at_cleanup')
  19567.         begin
  19568.             alter table sysmergearticles add maxversion_at_cleanup int NOT NULL default 1
  19569.             if @@ERROR <> 0 return 1
  19570.         end
  19571.  
  19572.         if not exists (select * from sysobjects where name = 'sysmergeschemaarticles')
  19573.             begin                
  19574.                 create table dbo.sysmergeschemaarticles 
  19575.                 (   name                    sysname             NOT NULL,
  19576.                     type                    tinyint             NULL,
  19577.                     objid                   int                 NOT NULL,
  19578.                     artid                   uniqueidentifier    NOT NULL,
  19579.                     description             nvarchar(255)       NULL,
  19580.                     pre_creation_command    tinyint             NULL,
  19581.                     pubid                   uniqueidentifier    NOT NULL,
  19582.                     status                  tinyint             NULL,
  19583.                     creation_script         nvarchar(255)       NULL,
  19584.                     schema_option           binary(8)           NULL,
  19585.                     destination_object      sysname             NOT NULL,
  19586.                     destination_owner       sysname             NULL
  19587.                     -- Note: Please update sysmergeextendedarticlesview whenever
  19588.                     -- there is a schema change in sysmergeschemaarticles
  19589.                 )
  19590.                 
  19591.                 exec dbo.sp_MS_marksystemobject sysmergeschemaarticles
  19592.                 create unique clustered index uc1sysmergeschemaarticles on sysmergeschemaarticles(artid, pubid)
  19593.  
  19594.  
  19595.             end
  19596.  
  19597.         if not exists (select * from sysobjects where name = 'MSmerge_errorlineage')
  19598.             begin        
  19599.                 create table dbo.MSmerge_errorlineage (
  19600.                 tablenick        int NOT NULL,
  19601.                 rowguid            uniqueidentifier NOT NULL,
  19602.                 lineage            varbinary(255)
  19603.                 )
  19604.                 exec dbo.sp_MS_marksystemobject MSmerge_errorlineage
  19605.                 create unique clustered index uc1errorlineage on MSmerge_errorlineage(tablenick, rowguid)
  19606.                 
  19607.                 grant select on MSmerge_errorlineage to public
  19608.             end
  19609.  
  19610.         if not exists (select * from sysobjects where name = 'MSmerge_altsyncpartners')
  19611.             begin            
  19612.                 create table dbo.MSmerge_altsyncpartners (
  19613.                     subid                 uniqueidentifier     not null,
  19614.                     alternate_subid     uniqueidentifier     not null,
  19615.                     description            nvarchar(255)        NULL
  19616.  
  19617.                 )
  19618.  
  19619.                 exec dbo.sp_MS_marksystemobject MSmerge_altsyncpartners
  19620.  
  19621.                 create unique clustered index uciMSmerge_altsyncpartners on 
  19622.                     dbo.MSmerge_altsyncpartners(subid, alternate_subid)
  19623.                 
  19624.             end
  19625.  
  19626.  
  19627.         -- create view now that sysmergearticles is altered and sysmergeextendedarticles is created
  19628.         if exists (select * from sysobjects where name='sysmergeextendedarticlesview')
  19629.         begin
  19630.             drop view dbo.sysmergeextendedarticlesview
  19631.         end    
  19632.  
  19633.         -- cannot create view directly in proc
  19634.         exec ('create view dbo.sysmergeextendedarticlesview
  19635.                    as
  19636.                select name, type, objid, sync_objid, view_type, artid, description, pre_creation_command, pubid,
  19637.                nickname, column_tracking, status, conflict_table, creation_script, conflict_script, article_resolver,
  19638.                ins_conflict_proc, insert_proc, update_proc, select_proc, schema_option, destination_object,
  19639.                resolver_clsid, subset_filterclause, missing_col_count, missing_cols, columns, resolver_info,
  19640.                view_sel_proc, gen_cur, excluded_cols, excluded_col_count, vertical_partition, identity_support,
  19641.                destination_owner, before_image_objid, before_view_objid, verify_resolver_signature, 
  19642.                allow_interactive_resolver, fast_multicol_updateproc, check_permissions, maxversion_at_cleanup                   
  19643.                from sysmergearticles
  19644.                union all
  19645.                select name, type, objid, NULL, NULL, artid, description, pre_creation_command, pubid, 
  19646.                NULL, NULL, status, NULL, creation_script, NULL, NULL, 
  19647.                NULL, NULL, NULL, NULL, schema_option, destination_object, 
  19648.                NULL, NULL, NULL, NULL, NULL, NULL, 
  19649.                NULL, NULL, NULL, NULL, NULL, NULL, 
  19650.                destination_owner, NULL, NULL, NULL, 
  19651.                0, 0, 0, NULL 
  19652.                from sysmergeschemaarticles
  19653.                go')
  19654.  
  19655.         exec dbo.sp_MS_marksystemobject sysmergeextendedarticlesview
  19656.  
  19657.         -- Do not regenerate views, procs if this is called from sp_restoredbreplication. Restore only
  19658.         -- needs to update schema, then it can call existing system procs to remove db replication cleanly
  19659.         if @skip_procgen = 0
  19660.         begin
  19661.             select @artnick = min(a.nickname) from sysmergearticles a inner join sysmergepublications p on p.pubid = a.pubid where p.snapshot_ready =1
  19662.             while @artnick is not null
  19663.             begin
  19664.                 -- find base table to compute number of columns
  19665.                 select @objid = objid, @col_track = column_tracking
  19666.                     from sysmergearticles where nickname = @artnick
  19667.  
  19668.                 -- regenerate the triggers
  19669.                 select @source_owner = user_name(uid), @source_object = name from sysobjects where id = @objid
  19670.                 select @qualified_name = QUOTENAME(@source_owner) + '.' + QUOTENAME(@source_object)
  19671.                 exec dbo.sp_MSaddmergetriggers @qualified_name, NULL, @col_track
  19672.  
  19673.                 /* Loop through all articles that this table is involved in and regenerate the article procs */
  19674.                 declare hcArtCursor CURSOR LOCAL FAST_FORWARD FOR select artid, pubid from sysmergearticles where nickname = @artnick order by artid, pubid
  19675.                 
  19676.                 OPEN hcArtCursor
  19677.                 FETCH hcArtCursor INTO @artid, @pubid
  19678.                 WHILE (@@fetch_status <> -1)
  19679.                     BEGIN
  19680.                         select @pubname = name, @snapshot_ready = snapshot_ready from sysmergepublications where pubid = @pubid
  19681.                         -- regenerate procs, triggers, and views only for articles with snapshot ready
  19682.                         if @snapshot_ready>0
  19683.                             begin
  19684.                                 declare @rgcol nvarchar(270)
  19685.                                 declare @indname nvarchar(270)
  19686.                                 declare @quotedname nvarchar(270)
  19687.                                 declare @conflict_table sysname
  19688.                                 declare @conflict_table_id int
  19689.                                 declare @owner sysname
  19690.                                 select @article = name, @conflict_table=conflict_table, @conflict_table_id=object_id(conflict_table)  
  19691.                                     from sysmergearticles where artid = @artid and pubid = @pubid
  19692.  
  19693.                                 --make sure conflict table has already got the indexes needed for performance enhancement
  19694.                                 --if not there we will add it up
  19695.                                  if ( @conflict_table_id is not null) and not exists 
  19696.                                      (select * from sysindexes where id = @conflict_table_id and keys is not null)
  19697.                                  begin
  19698.                                     select @owner=user_name(uid) from sysobjects where id= @conflict_table_id
  19699.                                     select @rgcol = QUOTENAME(name) from syscolumns 
  19700.                                         where id = @objid and ColumnProperty(id, name, 'isrowguidcol') = 1
  19701.                                     select @indname = 'uc_' + @conflict_table
  19702.                                     if len(@indname) > 128
  19703.                                     begin
  19704.                                         select @indname = substring(@indname,1,92) + convert(nvarchar(36), newid())
  19705.                                     end
  19706.                                     set @indname = QUOTENAME(@indname)
  19707.                                     set @quotedname = QUOTENAME(@owner) + '.' + QUOTENAME(@conflict_table)
  19708.                                     exec ('Create unique clustered index ' + @indname + ' on ' + @quotedname +
  19709.                                         ' (' + @rgcol + ', origin_datasource)' )
  19710.                                     if @@error <> 0
  19711.                                         return (1)
  19712.                                 end
  19713.                                 
  19714.                                 -- remake the articles procs
  19715.                                 exec @retcode = dbo.sp_MSsetartprocs @publication = @pubname,   @article = @article, @force_flag = 1
  19716.                                 if @@ERROR <>0 OR @retcode <>0 
  19717.                                     return (1)
  19718.                             END
  19719.                         FETCH hcArtCursor INTO @artid, @pubid
  19720.                     END                         
  19721.                 CLOSE hcArtCursor
  19722.                 DEALLOCATE hcArtCursor
  19723.  
  19724.                 -- we no longer try to delete metadata rows that might have truncated colv1
  19725.                 --  deleting can cause non-convergence problems where they previously didn't
  19726.                 --  exist, so we will try to patch up any truncated colv1 values in the merge agent.
  19727.                 
  19728.                 -- find next article
  19729.                 select @artnick = min(a.nickname) from sysmergearticles a inner join sysmergepublications p on p.pubid = a.pubid where p.snapshot_ready > 0 and a.nickname > @artnick
  19730.             end -- end colv metadata fixup, article proc and trigger re-gen
  19731.  
  19732.             -- Loop over publications and recreate the views, skipping publications where snapshot is not ready
  19733.             select @pubname = min(name) from sysmergepublications where UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name() and snapshot_ready > 0
  19734.             while @pubname is not null
  19735.             begin
  19736.                 -- remake the publication views
  19737.                 exec dbo.sp_MSpublicationview @pubname, 1
  19738.                 select @pubname = min(name) from sysmergepublications where name > @pubname and UPPER(publisher)=UPPER(@@SERVERNAME) and publisher_db=db_name() and snapshot_ready > 0
  19739.  
  19740.             end
  19741.         end -- end @skip_procgen
  19742.     end -- end sysmergearticles modifications
  19743.  
  19744.  
  19745.     SELECT @table_name = N'MSmerge_tombstone'
  19746.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_tombstone' )
  19747.     BEGIN
  19748.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'unc3MSmerge_tombstone' AND id = OBJECT_ID('MSmerge_tombstone'))
  19749.             drop index MSmerge_tombstone.unc3MSmerge_tombstone
  19750.         
  19751.     END
  19752.  
  19753.     SELECT @table_name = N'MSmerge_contents'
  19754.     IF EXISTS ( SELECT * FROM sysobjects WHERE name = 'MSmerge_contents' )
  19755.     BEGIN
  19756.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc2MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  19757.             drop index MSmerge_contents.nc2MSmerge_contents
  19758.  
  19759.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc3MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  19760.             drop index MSmerge_contents.nc3MSmerge_contents
  19761.  
  19762.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'nc4MSmerge_contents' AND id = OBJECT_ID('MSmerge_contents'))
  19763.             drop index MSmerge_contents.nc4MSmerge_contents
  19764.  
  19765.         IF EXISTS (SELECT * FROM sysindexes WHERE name = 'unc3SycContents' AND id = OBJECT_ID('MSmerge_contents'))
  19766.             drop index MSmerge_contents.unc3SycContents
  19767.         
  19768.         create index nc2MSmerge_contents on MSmerge_contents(generation)
  19769.         if @@ERROR <> 0 return 1
  19770.  
  19771.         create index nc3MSmerge_contents on MSmerge_contents(partchangegen)
  19772.         if @@ERROR <> 0 return 1
  19773.  
  19774.         create index nc4MSmerge_contents on MSmerge_contents(rowguid)
  19775.         if @@ERROR <> 0 return 1
  19776.     END
  19777.  
  19778.     if (exists (select * from sysobjects where name = 'sysmergearticles'))
  19779.     begin
  19780.         -- before image tables
  19781.         declare @binames table (biname sysname)
  19782.         insert into @binames select name from sysobjects 
  19783.                                 where xtype='U' 
  19784.                                 and name like 'MS_bi%'
  19785.                                 and id in (select before_image_objid from sysmergearticles)
  19786.         declare @biname sysname
  19787.         set @biname= (select top 1 biname from @binames)
  19788.         while @biname is not null
  19789.         begin
  19790.             set @cmd= 'drop index ' + @biname + '.' + @biname + '_gen'
  19791.             exec dbo.sp_executesql @cmd
  19792.             set @cmd= 'create clustered index ' + @biname + '_gen on ' + @biname + '(generation)'
  19793.             exec dbo.sp_executesql @cmd
  19794.             delete from @binames where biname=@biname
  19795.             set @biname= (select top 1 biname from @binames)
  19796.         end
  19797.     end
  19798.  
  19799.     -- remove orphaned rows in MSmerge_contents
  19800.     if (
  19801.             exists (select * from sysobjects where name = 'sysmergearticles') and
  19802.             exists (select * from sysobjects where name = 'sysmergepublications') and
  19803.             exists (select * from sysobjects where name = 'MSmerge_genhistory') and
  19804.             exists (select * from sysobjects where name = 'MSmerge_contents') and
  19805.             exists (select * from sysobjects where name = 'MSmerge_tombstone')
  19806.         )
  19807.     begin
  19808.         exec @retcode= sp_MSpurgecontentsorphans
  19809.         if @retcode<>0 or @@error<>0 return 1
  19810.     end
  19811. end
  19812. GO
  19813. exec sp_MS_marksystemobject 'sp_vupgrade_mergetables'
  19814. go
  19815.  
  19816. raiserror('Creating procedure sp_vupgrade_subpass', 0,1)
  19817. GO
  19818. create procedure sp_vupgrade_subpass
  19819. as
  19820. begin
  19821.     /* 
  19822.      * Upgrade replication ftp_password and distributor_passwords
  19823.      * in subscriber database.
  19824.      *
  19825.      * Setup version upgrade procedure call order:
  19826.      *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_subpass
  19827.     */
  19828.     begin transaction
  19829.  
  19830.     /*
  19831.      * MSsubscription_properties
  19832.     */
  19833.     if exists (select name from sysobjects where name='MSsubscription_properties')
  19834.     begin
  19835.         if not exists (select * from syscolumns where id = Object_Id('MSsubscription_properties') and name = 'ftp_password' and length = '1048')
  19836.         begin
  19837.             declare @dbname sysname
  19838.             declare @cmptlevel tinyint
  19839.             set @dbname = db_name()
  19840.             select @cmptlevel = cmptlevel from master..sysdatabases where name = @dbname collate database_default
  19841.             if @cmptlevel < 70
  19842.             begin
  19843.                                 raiserror (15048, -1, -1, 70, 70, 70, 80)
  19844.             end
  19845.             else
  19846.             begin
  19847.                     /*
  19848.                  * alter ftp_password column from sysname to nvarchar(524)
  19849.                 */
  19850.                 exec( 'alter table MSsubscription_properties alter column ftp_password nvarchar(524)' )
  19851.                 exec( 'alter table MSsubscription_properties alter column distributor_password nvarchar(524)' )
  19852.                 exec( 'alter table MSsubscription_properties alter column publisher_password nvarchar(524)' )
  19853.                 exec( 'alter table MSsubscription_properties alter column dts_package_password nvarchar(524)' )
  19854.             end
  19855.  
  19856.             /*
  19857.              * convert all the ftp_passwords to new encryption
  19858.              */
  19859.             declare @ftp_password nvarchar(524)
  19860.             declare @distributor_password nvarchar(524)
  19861.             declare @publisher_password nvarchar(524)
  19862.             declare @dts_package_password nvarchar(524)
  19863.             declare @retcode int
  19864.  
  19865.             declare cur_MSsubscription_properties CURSOR LOCAL FORWARD_ONLY for 
  19866.             select ftp_password, distributor_password, publisher_password, dts_package_password
  19867.             from MSsubscription_properties
  19868.             for update of ftp_password, distributor_password, publisher_password, dts_package_password
  19869.         
  19870.             open cur_MSsubscription_properties
  19871.             fetch next from cur_MSsubscription_properties into @ftp_password, @distributor_password, @publisher_password, @dts_package_password
  19872.             while ( @@fetch_status <> -1 )
  19873.             begin
  19874.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @ftp_password OUTPUT
  19875.                 IF @@error <> 0 OR @retcode <> 0
  19876.                 begin
  19877.                     rollback transaction
  19878.                     return 1
  19879.                 end
  19880.                       
  19881.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @distributor_password OUTPUT
  19882.                 IF @@error <> 0 OR @retcode <> 0
  19883.                 begin
  19884.                     rollback transaction
  19885.                     return 1
  19886.                 end
  19887.     
  19888.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @publisher_password OUTPUT
  19889.                 IF @@error <> 0 OR @retcode <> 0
  19890.                 begin
  19891.                     rollback transaction
  19892.                     return 1
  19893.                 end
  19894.  
  19895.                 EXEC @retcode = master.dbo.xp_repl_convert_encrypt @dts_package_password OUTPUT
  19896.                 IF @@error <> 0 OR @retcode <> 0
  19897.                 begin
  19898.                     rollback transaction
  19899.                     return 1
  19900.                 end
  19901.            
  19902.                 update MSsubscription_properties
  19903.                 set ftp_password=@ftp_password, distributor_password=@distributor_password, publisher_password=@publisher_password, dts_package_password=@dts_package_password
  19904.                 where current of cur_MSsubscription_properties
  19905.         
  19906.                     fetch next from cur_MSsubscription_properties into @ftp_password, @distributor_password, @publisher_password, @dts_package_password
  19907.             end
  19908.         end
  19909.     end
  19910.     commit transaction
  19911. end
  19912. GO
  19913. exec sp_MS_marksystemobject 'sp_vupgrade_subpass'
  19914. go
  19915.  
  19916. raiserror('Creating procedure sp_vupgrade_MSsubscription_properties', 0,1)
  19917. GO
  19918. create procedure sp_vupgrade_MSsubscription_properties
  19919. as
  19920. begin
  19921. /* 
  19922.  * Process schema and metadata changes common to transactional and merge MSsubscription_properties.
  19923.  *
  19924.  * Setup version upgrade procedure call order:
  19925.  *    sp_vupgrade_replication -> sp_vupgrade_subscription_databases -> sp_vupgrade_MSsubscription_properties
  19926. */
  19927.     set nocount on 
  19928.  
  19929.     declare @cmd nvarchar(1000)
  19930.     declare @table_name sysname
  19931.  
  19932.     -- raiserror('sp_vupgrade_MSsubscription_properties', 0,1)
  19933.  
  19934.     if exists( select * from sysobjects where name = 'MSsubscription_properties'
  19935.         and type = 'U')
  19936.     begin
  19937.         -- Add FTP properties to MSsubscription_properties.  
  19938.         if not exists (select * from syscolumns where name = 'ftp_address' and
  19939.             id = OBJECT_ID('MSsubscription_properties'))
  19940.         begin
  19941.             alter table MSsubscription_properties ADD ftp_address sysname NULL
  19942.             if @@ERROR <> 0
  19943.                 return 1
  19944.         end
  19945.  
  19946.         if not exists (select * from syscolumns where name = 'ftp_port' and
  19947.             id = OBJECT_ID('MSsubscription_properties'))
  19948.         begin
  19949.             alter table MSsubscription_properties ADD ftp_port int NULL
  19950.             if @@ERROR <> 0
  19951.                 return 1
  19952.         end
  19953.  
  19954.         if not exists (select * from syscolumns where name = 'ftp_login' and
  19955.             id = OBJECT_ID('MSsubscription_properties'))
  19956.         begin
  19957.             alter table MSsubscription_properties ADD ftp_login sysname NULL
  19958.             if @@ERROR <> 0
  19959.                 return 1
  19960.         end
  19961.  
  19962.         if not exists (select * from syscolumns where name = 'ftp_password' and
  19963.             id = OBJECT_ID('MSsubscription_properties'))
  19964.         begin
  19965.             alter table MSsubscription_properties ADD ftp_password sysname NULL
  19966.             if @@ERROR <> 0
  19967.                 return 1
  19968.         end
  19969.  
  19970.         -- Portable snapshot (Shiloh)
  19971.         if not exists (select * from syscolumns where name = 'alt_snapshot_folder' and
  19972.             id = OBJECT_ID('MSsubscription_properties'))
  19973.         begin
  19974.             alter table MSsubscription_properties ADD alt_snapshot_folder nvarchar(255) NULL
  19975.             if @@ERROR <> 0
  19976.                 return 1
  19977.         end
  19978.  
  19979.         if not exists (select * from syscolumns where name = 'working_directory' and
  19980.             id = OBJECT_ID('MSsubscription_properties'))
  19981.         begin
  19982.  
  19983.             alter table MSsubscription_properties ADD working_directory nvarchar(255) NULL
  19984.             if @@ERROR <> 0
  19985.                 return 1
  19986.         end
  19987.  
  19988.         -- Subscriber need only set this bit and have valid login info to publisher (Shiloh)
  19989.         if not exists (select * from syscolumns where name = 'use_ftp' and
  19990.             id = OBJECT_ID('MSsubscription_properties'))
  19991.         begin
  19992.  
  19993.             alter table MSsubscription_properties ADD use_ftp bit default 0 NOT NULL
  19994.             if @@ERROR <> 0
  19995.                 return 1
  19996.         end
  19997.  
  19998.         -- Since ftp login information is not required to be persisted at the 
  19999.         -- database anymore and the use_ftp column is now the sole indicator 
  20000.         -- of whether ftp is going to be used for a particular subscription,
  20001.         -- set the use_ftp column to 1 for subscriptions that used to have
  20002.         -- a non-null ftp address
  20003.         if exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  20004.             name = 'ftp_address')
  20005.         begin
  20006.             -- must exec in separate process; deferred syntax will fail if update references non-existent column
  20007.             select @cmd = 'update dbo.MSsubscription_properties set use_ftp = 1 where ftp_address is not null and ftp_address <> N'''''
  20008.             exec (@cmd)
  20009.         end 
  20010.  
  20011.         -- Transformable subscriptions (Shiloh)
  20012.         if not exists (select * from syscolumns where name = 'dts_package_name' and
  20013.             id = OBJECT_ID('MSsubscription_properties'))
  20014.         begin
  20015.             alter table MSsubscription_properties ADD dts_package_name sysname NULL
  20016.             if @@ERROR <> 0
  20017.                 return 1
  20018.         end
  20019.  
  20020.         if not exists (select * from syscolumns where name = 'dts_package_password' and
  20021.             id = OBJECT_ID('MSsubscription_properties'))
  20022.         begin
  20023.             alter table MSsubscription_properties ADD dts_package_password nvarchar(524) NULL
  20024.             if @@ERROR <> 0
  20025.                 return 1
  20026.         end
  20027.  
  20028.         if not exists (select * from syscolumns where name = 'dts_package_location' and
  20029.             id = OBJECT_ID('MSsubscription_properties'))
  20030.         begin
  20031.             alter table MSsubscription_properties ADD dts_package_location int default 1 NOT NULL
  20032.             if @@ERROR <> 0
  20033.                 return 1
  20034.         end
  20035.  
  20036.         -- Windows Synchronization Manager support (Shiloh)
  20037.         if not exists (select * from syscolumns where name = 'enabled_for_syncmgr' and
  20038.             id = OBJECT_ID('MSsubscription_properties'))
  20039.         begin
  20040.             alter table MSsubscription_properties ADD enabled_for_syncmgr bit default 0 NOT NULL
  20041.             if @@ERROR <> 0
  20042.                 return 1
  20043.         end
  20044.  
  20045.         -- Remote (DCOM) agents support (Shiloh)
  20046.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  20047.             name = 'offload_agent')
  20048.         begin
  20049.             alter table MSsubscription_properties ADD offload_agent bit default 0 NOT NULL
  20050.             if @@ERROR <> 0
  20051.                 return 1
  20052.         end
  20053.  
  20054.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  20055.             name = 'offload_server')
  20056.         begin
  20057.             alter table MSsubscription_properties ADD offload_server sysname default NULL
  20058.             if @@ERROR <> 0
  20059.                 return 1
  20060.         end        
  20061.  
  20062.         -- Dynamic snapshot location (Shiloh)
  20063.         if not exists (select * from syscolumns where id = object_id('MSsubscription_properties') and
  20064.             name = 'dynamic_snapshot_location')
  20065.         begin
  20066.             alter table MSsubscription_properties ADD dynamic_snapshot_location sysname default NULL
  20067.             
  20068.             if @@ERROR <> 0
  20069.                 return 1
  20070.         end
  20071.  
  20072.         --    MSsubscription_properties indexes (SQL7.0 SP1)
  20073.         select @table_name = N'MSsubscription_properties'
  20074.         if exists( select * from sysobjects where name = 'MSsubscription_properties' ) 
  20075.         begin
  20076.             if exists( select publication, publisher_db, publisher
  20077.                 from MSsubscription_properties
  20078.                 group by publication, publisher_db, publisher
  20079.                 having count(*) > 1 )
  20080.                 raiserror(21203, 10, 2, @table_name)
  20081.             else
  20082.                 if not exists( select * from sysindexes where name = 'uc1MSsubscription_properties' and
  20083.                     id = OBJECT_ID('MSsubscription_properties') )
  20084.                     create unique clustered index uc1MSsubscription_properties on
  20085.                     MSsubscription_properties(publication, publisher_db, publisher)
  20086.         end
  20087.     end
  20088.  
  20089. end
  20090. go
  20091. exec sp_MS_marksystemobject 'sp_vupgrade_MSsubscription_properties'
  20092. go
  20093.  
  20094. raiserror('Creating procedure sp_vupgrade_replication', 0,1)
  20095. GO
  20096.  
  20097. create procedure sp_vupgrade_replication ( @login sysname = N'sa', @password sysname = N'', @ver_old int = 517, @force_remove tinyint = 0, @security_mode bit = 0 )
  20098. as
  20099. begin
  20100. /* 
  20101.  * Dispatcher proc for handling schema and metadata changes during setup initiated version upgrade 
  20102.  * for replication components. Any schema changes to replication system tables may require modifications 
  20103.  * here to maintain upgrade path. All modifications called in these procs are within "if exists" checks
  20104.  * making them repeatable for debugging and to support incremental upgrades (e.g. Beta 1 to Beta 2 to RTM)
  20105.  * 
  20106.  * If server is a distributor, run new instdist.sql against all distribution dbs.
  20107.  *
  20108.  * This proc gets called by setup at the end of an install over an existing version.
  20109. */
  20110.  
  20111.     set nocount on 
  20112.  
  20113.     declare @dbname sysname
  20114.     declare @has_dbaccess bit
  20115.     declare @install_path nvarchar(255)
  20116.     declare @osql_path nvarchar(260)
  20117.     declare @osql_cmd nvarchar(512)
  20118.     declare @osql_for_nt int
  20119.     declare @retcode int
  20120.     declare @platform_nt binary
  20121.     declare @db_distbit int
  20122.     declare @ver_min             int
  20123.  
  20124.     select @db_distbit = 16
  20125.     select @platform_nt = 0x1
  20126.  
  20127.     -- raiserror('sp_vupgrade_replication', 0,1) with nowait
  20128.  
  20129.     /*
  20130.      * obsolete check; ver check was to prevent repl upgrade from
  20131.      * versions prior to SQL7.0 Beta 3; check is removed by setting @ver_min = -1
  20132.     */
  20133.     select @ver_min= -1 -- change if later wish to support a minimum upgrade version
  20134.     if ( @ver_old < @ver_min ) or ( @force_remove = 1 )
  20135.         exec dbo.sp_removesrvreplication
  20136.     else
  20137.     begin
  20138.  
  20139.         /* 
  20140.          * always need to run instdist.sql to update distribution databases on a distributor
  20141.          * setup must restart in non-single user mode so we can shell out to run instdist.sql scripts
  20142.         */
  20143.         if exists( select * from master..sysdatabases where category & @db_distbit = @db_distbit )
  20144.         begin
  20145.  
  20146.             /* 
  20147.             ** Get installation path -- osql client (TOOLS) path
  20148.             */
  20149.             EXECUTE @retcode = master.dbo.sp_MSgettools_path @osql_path OUTPUT
  20150.             IF ( @@ERROR <> 0 ) OR ( @retcode <> 0 ) or ( @osql_path is NULL ) or ( @osql_path = '' )
  20151.             BEGIN
  20152.                 RETURN (1)
  20153.             END
  20154.  
  20155.             /* 
  20156.             ** Get installation path -- instance specific (INSTALL) directory
  20157.             */
  20158.             exec @retcode = master.dbo.sp_MSget_setup_paths
  20159.                 @sql_path = @install_path output
  20160.             IF @@ERROR<> 0 OR @retcode <> 0 or @install_path is NULL or @install_path=N''
  20161.             BEGIN
  20162.                 RETURN (1)
  20163.             END
  20164.  
  20165.             -- Set the flag for platform
  20166.             if (( platform() & @platform_nt = @platform_nt ))
  20167.                 select @osql_for_nt = 1
  20168.             else
  20169.                 select @osql_for_nt = 0
  20170.  
  20171.             declare cur_distdb CURSOR LOCAL FAST_FORWARD for 
  20172.                 select name, has_dbaccess(name) from master..sysdatabases 
  20173.                     where category & @db_distbit = @db_distbit
  20174.                 for read only
  20175.             
  20176.             open cur_distdb
  20177.             fetch cur_distdb into @dbname, @has_dbaccess
  20178.             while ( @@fetch_status <> -1 )
  20179.             begin
  20180.  
  20181.                 -- if distribution database is available upgrade it; if offline error out
  20182.                 if ( @has_dbaccess = 1 )
  20183.                 begin
  20184.                     raiserror( 21374, 0, 1, @dbname) with nowait
  20185.  
  20186.                     /*
  20187.                      * Format osql cmd line appropriate for security mode and OS to run instdist.sql against
  20188.                      * each distribution database. Instdist.sql will recompile procs and will also do some
  20189.                      * schema and metadata upgrade of changed replication tables. Query timeout increased to
  20190.                      * make enough time for alter tables in instdist.sql run for upgrade to complete.
  20191.                     */
  20192.                     if ( @osql_for_nt = 1 )
  20193.                         select @osql_cmd = N'" "'
  20194.                     else
  20195.                         select @osql_cmd = N' "'
  20196.                     
  20197.                     -- Cannot specify -S w/ -E for local execution, SID does not map (nofix)
  20198.                     if ( @security_mode = 1 and @osql_for_nt = 1 )
  20199.                     begin
  20200.                         select @osql_cmd = @osql_cmd + @osql_path + '\binn\osql" -E '
  20201.                         if serverproperty('instancename') is not null
  20202.                             select @osql_cmd = @osql_cmd + ' -S"' + @@SERVERNAME + '" '
  20203.                     end
  20204.                     else
  20205.                         select @osql_cmd = @osql_cmd + @osql_path + '\binn\osql" -U' + isnull(@login, N'sa') + ' -P' + isnull(@password, N'') + ' -S"' + @@SERVERNAME + '" '
  20206.  
  20207.                     select @osql_cmd = @osql_cmd + ' -l30 -t120 '
  20208.                     select @osql_cmd = @osql_cmd + ' -b ' + ' -d' + @dbname
  20209.                     select @osql_cmd = @osql_cmd +    ' -i' + '"' + @install_path + '\install\instdist.sql"' + 
  20210.                                                     ' -o' + '"' + @install_path + '\install\instdist.out"'            
  20211.  
  20212.                     if (@osql_for_nt = 1)
  20213.                         select @osql_cmd = @osql_cmd + ' "'
  20214.  
  20215.                      exec @retcode = master..xp_cmdshell @osql_cmd
  20216.                     if @retcode <> 0 or @@error <> 0
  20217.                     begin
  20218.                         raiserror (14113, 16, -1, @osql_cmd, 'instdist.out')
  20219.                     end
  20220.  
  20221.                     /*
  20222.                      * Process schema and metadata changes for each distribution database
  20223.                     */
  20224.  
  20225.                     select @dbname = quotename(@dbname)
  20226.                     exec ('use '+ @dbname + ' exec dbo.sp_vupgrade_distdb')
  20227.                     if @@error <> 0
  20228.                         return(1)
  20229.                 end
  20230.                 else
  20231.                 begin
  20232.                     /* Report informational message stating distribution
  20233.                     ** database is not accessible.
  20234.                     */
  20235.                     raiserror( 21378, 10, 1, @dbname) with nowait
  20236.                 end
  20237.                 
  20238.                 fetch next from cur_distdb into @dbname, @has_dbaccess
  20239.             end
  20240.             close cur_distdb
  20241.             deallocate cur_distdb
  20242.         end
  20243.  
  20244.     
  20245.         -- Update subscription database schema
  20246.         exec @retcode = dbo.sp_vupgrade_subscription_databases
  20247.         if @retcode <> 0 or @@error <> 0
  20248.             return (1)
  20249.  
  20250.  
  20251.     end
  20252.  
  20253.     return (0)
  20254.  
  20255. end
  20256. go
  20257.  
  20258. exec dbo.sp_MS_marksystemobject sp_vupgrade_replication
  20259. go
  20260.  
  20261.  
  20262. raiserror('Creating procedure sp_vupgrade_distdb', 0,1)
  20263. go
  20264. create procedure sp_vupgrade_distdb 
  20265. as
  20266. begin
  20267. /* 
  20268.  * Process schema and metadata changes specific to a distribution database. Some schema modifications
  20269.  * may have already been made by the apply of instdist.sql against the distribution database. Both steps
  20270.  * are needed for a complete distribution database upgrade.
  20271.  *
  20272.  * Setup version upgrade procedure call order:
  20273.  *    sp_vupgrade_replication -> sp_vupgrade_distdb
  20274. */
  20275.  
  20276.     set nocount on
  20277.  
  20278.     declare @table_name sysname
  20279.     declare @retcode integer
  20280.  
  20281.     -- raiserror('sp_vupgrade_publisher', 0,1) with nowait
  20282.     /*
  20283.      * MSdistribution_agents
  20284.     */
  20285.     if exists (select name from sysobjects where name='MSdistribution_agents')
  20286.     begin
  20287.         if not exists (select * from syscolumns where id = object_id('MSdistribution_agents') and name = 'queue_server')
  20288.         begin
  20289.             alter table MSdistribution_agents add queue_server sysname null
  20290.             EXEC dbo.sp_MSupdate_mqserver_distdb
  20291.         end
  20292.     end
  20293.  
  20294. end
  20295. go
  20296.  
  20297. exec dbo.sp_MS_marksystemobject sp_vupgrade_distdb
  20298. go
  20299.  
  20300.  
  20301. raiserror('Creating procedure sp_vupgrade_publisher', 0,1)
  20302. go
  20303. create procedure sp_vupgrade_publisher @ver_old int, @ver_retention int
  20304. as
  20305. begin
  20306. /* 
  20307.  * Process schema and metadata changes specific to a publisher and dispatch calls to sp_vupgrade_publisherdb
  20308.  * for any databases marked with the publishing bits.
  20309.  *
  20310.  * Setup version upgrade procedure call order:
  20311.  *    sp_vupgrade_replication -> sp_vupgrade_publisher
  20312. */
  20313.  
  20314.     set nocount on
  20315.  
  20316.     declare @proc_name            nvarchar(350)
  20317.     declare @publication        sysname
  20318.     declare @upgraded            bit 
  20319.     declare @retcode             int
  20320.     declare @publisher_db        nvarchar(270)
  20321.     declare @agentname            sysname
  20322.     declare @has_dbaccess        bit
  20323.  
  20324.     -- raiserror('sp_vupgrade_publisher', 0,1)
  20325.  
  20326.     /*
  20327.      * Expired subscription cleanup agent name needs set to localized string (message 20569) and 
  20328.      * jobstep set to correct procedure name based on name change between SQL7.0 and SQL7.5
  20329.     */
  20330.     set @agentname = formatmessage(20569)  
  20331.     
  20332.     update msdb.dbo.sysjobs
  20333.         set name = @agentname
  20334.         from msdb.dbo.sysjobs, msdb.dbo.sysjobsteps as s
  20335.         where msdb.dbo.sysjobs.job_id = s.job_id
  20336.         and 
  20337.         ( upper(s.command) = upper(N'EXEC sp_MScleanup_subscription') 
  20338.         or upper(s.command) = upper(N'EXEC dbo.sp_MScleanup_subscription') )
  20339.  
  20340.     update msdb.dbo.sysjobsteps 
  20341.         set  command = N'EXEC dbo.sp_expired_subscription_cleanup' 
  20342.         where upper(command) = upper(N'EXEC sp_MScleanup_subscription')
  20343.         or upper(command) = upper(N'EXEC dbo.sp_MScleanup_subscription')
  20344.             
  20345.     /*
  20346.      * Process schema and metadata changes for each publishing database on the publisher.
  20347.      * 
  20348.      * Transactional replication system tables at the publisher are updated by sp_vupgrade_publisherdb.
  20349.      * Most merge system tables exist in both the publishing and subscribing databases; merge schema 
  20350.      * and metadata changes are processed by a separate pass over all databases in sp_vupgrade_mergetables.
  20351.     */
  20352.     declare DC cursor local FAST_FORWARD for select distinct N'[' + replace(name, N']', N']]') + N']', has_dbaccess(name) from master..sysdatabases 
  20353.     --    where ((category & 4) = 4) or ((category & 1) = 1)
  20354.             WHERE name <> N'master' collate database_default
  20355.             AND name <> N'tempdb' collate database_default
  20356.             AND name <> N'msdb' collate database_default
  20357.         for read only
  20358.     open DC
  20359.     fetch DC into @publisher_db, @has_dbaccess
  20360.     while (@@fetch_status <> -1)
  20361.     begin
  20362.         -- upgrade repl tables in publishing dbs if needed
  20363.         -- skip any database in an offline state and write warning to upgrade log
  20364.         if ( @has_dbaccess = 1 )
  20365.         begin
  20366.             raiserror( 21375, 10, 1, @publisher_db) with nowait
  20367.  
  20368.             select @proc_name = @publisher_db + '.dbo.sp_vupgrade_publisherdb'
  20369.             exec @retcode = @proc_name 
  20370.                 @ver_old = @ver_old,
  20371.                 @ver_retention = @ver_retention
  20372.             if @retcode<>0 or @@ERROR<>0
  20373.             begin
  20374.                 close DC
  20375.                 deallocate DC
  20376.                 return (1)
  20377.             end
  20378.         end
  20379.         else
  20380.         begin 
  20381.             -- report informational message stating database is not accessible.
  20382.             raiserror( 21376, 10, 1, @publisher_db) with nowait
  20383.         end
  20384.  
  20385.         fetch DC into @publisher_db, @has_dbaccess
  20386.  
  20387.     end
  20388.     close DC
  20389.     deallocate DC
  20390.         
  20391.     /*
  20392.      * We need to mark sp_MScleanupmergepublisher as a startup procedure
  20393.      * if there are any databases enabled for merge replication.
  20394.      */
  20395.     if exists (select * from sysdatabases where (category & 4) <> 0)
  20396.     begin
  20397.         exec dbo.sp_procoption 'sp_MScleanupmergepublisher', 'startup', 'true'
  20398.     end
  20399.  
  20400. end
  20401. go
  20402.  
  20403. exec dbo.sp_MS_marksystemobject sp_vupgrade_publisher
  20404. go
  20405.  
  20406.  
  20407. raiserror('Creating procedure sp_vupgrade_syscol_status', 0,1)
  20408. go
  20409. create procedure sp_vupgrade_syscol_status
  20410. as
  20411. begin
  20412. /* 
  20413.  * Transactional published tables should have their column bits set to indicate they are published.
  20414.  *
  20415.  * Setup version upgrade procedure call order:
  20416.  *    sp_vupgrade_replication -> sp_vupgrade_publisher -> sp_vupgrade_publisherdb -> sp_vupgrade_syscol_status
  20417. */
  20418.  
  20419.     set nocount on 
  20420.  
  20421.     declare @artid int
  20422.     declare @src_objid int
  20423.     declare @columns binary(32)
  20424.     declare @this_col int
  20425.     declare @isset int
  20426.  
  20427.     -- raiserror('sp_vupgrade_syscol_status', 0,1) with nowait
  20428.  
  20429.     -- cursor through table based articles
  20430.     declare hCArt cursor local FAST_FORWARD for 
  20431.         select artid, objid, columns from sysarticles where type & 1 = 1
  20432.     open hCArt
  20433.     fetch hCArt into @artid, @src_objid, @columns
  20434.     while (@@fetch_status <> -1)
  20435.     begin
  20436.         -- cursor through columns on replicated object
  20437.         declare hCColid cursor local FAST_FORWARD for 
  20438.             select colid from syscolumns where id = @src_objid
  20439.         open hCColid
  20440.         fetch hCColid into @this_col
  20441.         while (@@fetch_status <> -1)
  20442.         begin
  20443.            exec @isset = dbo.sp_isarticlecolbitset @this_col, @columns
  20444.            if @isset != 0 
  20445.            begin
  20446.                 exec sp_MSarticlecol @artid, @this_col, 'publish', 'add'
  20447.            end
  20448.            fetch hCColid into @this_col
  20449.         end
  20450.         close hCColid
  20451.         deallocate hCColid
  20452.  
  20453.         fetch hCArt into @artid, @src_objid, @columns
  20454.     end
  20455.  
  20456.     close hCArt
  20457.     deallocate hCArt
  20458. end
  20459. go
  20460. exec dbo.sp_MS_marksystemobject sp_vupgrade_syscol_status
  20461. go
  20462.  
  20463. raiserror('Creating procedure sp_vupgrade_publisherdb', 0,1)
  20464. go
  20465. create procedure sp_vupgrade_publisherdb @ver_old int, @ver_retention int
  20466. as
  20467. begin
  20468. /* 
  20469.  * Process schema and metadata changes specific to a publishing database. Transactional replication 
  20470.  * system tables at the publisher are updated by sp_vupgrade_publisherdb; merge tables are not.
  20471.  * Most merge system tables exist in both the publishing and subscribing databases; merge schema 
  20472.  * and metadata changes are processed by a separate pass over all databases in sp_vupgrade_mergetables.
  20473.  *
  20474.  * Match column order of newly created table when adding columns.
  20475.  *
  20476.  * Setup version upgrade procedure call order:
  20477.  *    sp_vupgrade_replication -> sp_vupgrade_publisher -> sp_vupgrade_publisherdb
  20478. */
  20479.  
  20480.     set nocount on 
  20481.  
  20482.     declare @default_name sysname 
  20483.  
  20484.     -- raiserror('sp_vupgrade_publisherdb', 0,1) with nowait
  20485.  
  20486.     -- sysarticles 
  20487.     if exists( select name from sysobjects where name = 'sysarticles' )
  20488.     begin
  20489.         
  20490.         if exists( select * from syscolumns where id = object_id('dbo.sysarticles') and name = 'schema_option' )
  20491.         begin
  20492.             -- The following two-phase upgrade operation has to be atomic
  20493.             begin transaction
  20494.             save transaction sysarticles_upgrade 
  20495.     
  20496.                 -- For table articles which used to have the 
  20497.                 -- SQLDMOCreationScript_DRI_Primary (0x00000080) schema option enabled,
  20498.                 -- turn on the SQLDMOCreationScript_PKFKAsConstraints (0x00008000)
  20499.                 -- option
  20500.                 update sysarticles 
  20501.                    set schema_option = convert(int, schema_option) | convert(int, 0x00008000)
  20502.                   from sysobjects so
  20503.                 where (convert(int, schema_option) & 0x00000080) <> 0x00000000
  20504.                   and so.id = sysarticles.objid
  20505.                   and so.xtype = 'U'
  20506.         
  20507.                 if @@error <> 0
  20508.                     goto SYSARTICLE_ERROR
  20509.  
  20510.                 -- Enable both the SQLDMOCreationScript_DRI_PrimaryKey and
  20511.                 -- SQLDMOCreationScript_UniqueKeys options (0x00004000) if at least 
  20512.                 -- one of SQLDMOCreationScript_NonClusteredIndexes (0x00000010) and 
  20513.                 -- SQLDMOCreationScript_ClusteredIndexes (0x00000040) was enabled
  20514.                 -- or the table article belongs to a transactional publication  
  20515.                 update sysarticles 
  20516.                    set schema_option = convert(int, schema_option) |
  20517.                                         convert(int, 0x00004080)
  20518.                   from sysobjects so,
  20519.                        syspublications sp
  20520.                 where ((sysarticles.pubid = sp.pubid and sp.repl_freq = 0) 
  20521.                       or (convert(int, schema_option) & convert(int, 0x00000050) <> 
  20522.                           0x00000000)) 
  20523.                   and so.id = sysarticles.objid
  20524.                   and so.xtype = 'U'
  20525.  
  20526.                 if @@error <> 0
  20527.                     goto SYSARTICLE_ERROR
  20528.  
  20529.                 -- Skip over the error handling code
  20530.                 goto SYSARTICLE_END
  20531.         SYSARTICLE_ERROR:
  20532.             rollback transaction sysarticles_upgrade
  20533.             commit transaction
  20534.             return 1    
  20535.         SYSARTICLE_END:
  20536.             commit transaction 
  20537.         end
  20538.     end -- end of sysarticles upgrade
  20539.  
  20540.     -- syssubscriptions
  20541.     if exists (select name from sysobjects where name='syssubscriptions')
  20542.     begin
  20543.         if not exists (select * from syscolumns where id = object_id('syssubscriptions') and 
  20544.             name = 'queued_reinit')
  20545.         begin
  20546.             alter table syssubscriptions add queued_reinit bit default 0 not null
  20547.         end
  20548.  
  20549.     end -- end of syssubscriptions upgrade
  20550.  
  20551.     -- syspublications
  20552.     if exists (select name from sysobjects where name='syspublications')
  20553.     begin
  20554.  
  20555.         -- default_access column no longer used
  20556.         if exists (select * from syscolumns where id = object_id('syspublications') and
  20557.             name = 'default_access')
  20558.         begin
  20559.             alter table syspublications drop column default_access
  20560.         end 
  20561.  
  20562.         /*
  20563.          * Queued updating subscriptions option; conflict management settings added later in this proc
  20564.         */
  20565.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20566.             name = 'allow_queued_tran')
  20567.         begin
  20568.             alter table syspublications add allow_queued_tran bit default 0 not null
  20569.         end
  20570.  
  20571.         /*
  20572.          * Portable snapshot
  20573.         */
  20574.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'snapshot_in_defaultfolder')
  20575.         begin
  20576.             alter table syspublications add snapshot_in_defaultfolder bit default 1 not null
  20577.         end
  20578.     
  20579.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'alt_snapshot_folder')
  20580.         begin
  20581.             alter table syspublications add alt_snapshot_folder nvarchar(255) null
  20582.         end
  20583.  
  20584.         /*
  20585.          * Snapshot pre/post commands
  20586.         */
  20587.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'pre_snapshot_script')
  20588.         begin
  20589.             alter table syspublications add pre_snapshot_script nvarchar(255) null
  20590.         end
  20591.        
  20592.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'post_snapshot_script')
  20593.         begin
  20594.             alter table syspublications add post_snapshot_script nvarchar(255) null
  20595.         end
  20596.  
  20597.         /*
  20598.          * Snapshot compression
  20599.         */
  20600.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'compress_snapshot')
  20601.         begin
  20602.             alter table syspublications add compress_snapshot bit default 0 not null
  20603.         end
  20604.  
  20605.         /*
  20606.          * Post SQL7.0 FTP configuration stored at publisher
  20607.         */
  20608.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_address')
  20609.         begin
  20610.             alter table syspublications add ftp_address sysname null
  20611.         end
  20612.  
  20613.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_port')
  20614.         begin
  20615.             alter table syspublications add ftp_port int not null default 21
  20616.         end
  20617.  
  20618.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_subdirectory')
  20619.         begin
  20620.             alter table syspublications add ftp_subdirectory nvarchar(255) null
  20621.         end
  20622.  
  20623.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_login')
  20624.         begin
  20625.             alter table syspublications add ftp_login sysname null default N'anonymous'
  20626.         end
  20627.  
  20628.         if not exists (select * from syscolumns where id = object_id('syspublications') and name = 'ftp_password')
  20629.         begin
  20630.             alter table syspublications add ftp_password nvarchar(524) null
  20631.         end
  20632.  
  20633.         -- Since the ftp_address is now required to enable a publication for 
  20634.         -- internet, publications that were enabled for internet can not
  20635.         -- be upgraded automatically. So the enabled for internet option 
  20636.         -- is reset in the upgrade process. 
  20637.         if exists (select * from syscolumns where id = object_id('syspublications') and 
  20638.            name = 'enabled_for_internet')
  20639.         begin
  20640.             update dbo.syspublications 
  20641.                set enabled_for_internet = 0 
  20642.         end
  20643.  
  20644.         /*
  20645.          * Transformable subscriptions
  20646.         */
  20647.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20648.             name = 'allow_dts')
  20649.         begin
  20650.             alter table syspublications add allow_dts bit default 0 not null
  20651.         end
  20652.  
  20653.         /*
  20654.          * Attach & Go 
  20655.         */
  20656.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20657.             name = 'allow_subscription_copy')
  20658.         begin
  20659.             alter table syspublications add allow_subscription_copy bit default 0 not null
  20660.         end
  20661.  
  20662.         /*
  20663.          * Transactional conflict management
  20664.         */
  20665.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20666.             name = 'centralized_conflicts')
  20667.         begin
  20668.             alter table syspublications add centralized_conflicts bit NULL
  20669.         end
  20670.     
  20671.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20672.             name = 'conflict_retention')
  20673.         begin
  20674.             alter table syspublications add conflict_retention int NULL
  20675.         end
  20676.  
  20677.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20678.             name = 'conflict_policy')
  20679.         begin
  20680.             alter table syspublications add conflict_policy int NULL
  20681.         end
  20682.  
  20683.         /*
  20684.          * Attach & Go 
  20685.         */
  20686.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20687.             name = 'queue_type')
  20688.         begin
  20689.             alter table syspublications add queue_type int NULL
  20690.         end
  20691.  
  20692.         /*
  20693.          * Active Directory
  20694.         */
  20695.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20696.             name = 'ad_guidname')
  20697.         begin
  20698.             alter table syspublications add ad_guidname sysname null
  20699.         end
  20700.  
  20701.         if not exists (select * from syscolumns where id = object_id('syspublications') and 
  20702.             name = 'backward_comp_level')
  20703.         begin
  20704.             alter table syspublications add backward_comp_level int default 10 not null
  20705.         end
  20706.         
  20707.         /*
  20708.          * Schema only articles (views, procs, udfs)
  20709.         */
  20710.         if not exists (select * from sysobjects where name = 'sysschemaarticles')
  20711.         begin
  20712.             create table dbo.sysschemaarticles
  20713.             (
  20714.                 artid               int                 NOT NULL,
  20715.                 creation_script     nvarchar(255)       NULL,
  20716.                 description         nvarchar(255)       NULL,
  20717.                 dest_object         sysname             NOT NULL,
  20718.                 name                sysname             NOT NULL,
  20719.                 objid               int                 NOT NULL,
  20720.                 pubid               int                 NOT NULL,
  20721.                 pre_creation_cmd    tinyint             NOT NULL,
  20722.                 status              int                 NOT NULL,
  20723.                 type                tinyint             NOT NULL,
  20724.                 schema_option       binary(8)           NULL,
  20725.                 dest_owner          sysname             NULL
  20726.             )
  20727.             exec dbo.sp_MS_marksystemobject sysschemaarticles
  20728.  
  20729.             if not exists (select * from sysindexes where name = 'unc1sysschemaarticles')
  20730.             begin
  20731.                 create unique nonclustered index unc1sysschemaarticles
  20732.                     on sysschemaarticles(artid, pubid)
  20733.             end  
  20734.  
  20735.         end
  20736.  
  20737.         if exists (select * from sysobjects where name = 'sysextendedarticlesview')
  20738.         begin
  20739.             drop view dbo.sysextendedarticlesview
  20740.         end
  20741.         -- cannot create view directly in stored procedure            
  20742.         exec ( 'create view dbo.sysextendedarticlesview
  20743.                    as
  20744.                    select artid, columns, creation_script, del_cmd, description,
  20745.                    dest_table, filter, filter_clause, ins_cmd, name, objid, pubid, pre_creation_cmd,
  20746.                    status, sync_objid, type, upd_cmd, schema_option, dest_owner    
  20747.                    from sysarticles
  20748.                    union all
  20749.                    select artid, NULL, creation_script, NULL, description,
  20750.                    dest_object, NULL, NULL, NULL, name, objid, pubid, 
  20751.                    pre_creation_cmd, status, NULL, type, NULL, 
  20752.                    schema_option, dest_owner 
  20753.                    from sysschemaarticles' )
  20754.  
  20755.         exec dbo.sp_MS_marksystemobject 'sysextendedarticlesview'
  20756.  
  20757.         exec sp_vupgrade_syscol_status
  20758.  
  20759.     end
  20760.  
  20761.     -- sysarticleupdates
  20762.     if exists (select name from sysobjects where name='sysarticleupdates')
  20763.     begin
  20764.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  20765.             name = 'sync_upd_trig')
  20766.         begin
  20767.             alter table sysarticleupdates add sync_upd_trig int default 0 NOT NULL
  20768.         end
  20769.  
  20770.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  20771.             name = 'conflict_tableid')
  20772.         begin
  20773.             alter table sysarticleupdates add conflict_tableid int NULL
  20774.         end
  20775.  
  20776.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  20777.             name = 'ins_conflict_proc')
  20778.         begin
  20779.             alter table sysarticleupdates add ins_conflict_proc int NULL
  20780.         end
  20781.  
  20782.         if not exists (select * from syscolumns where id = object_id('sysarticleupdates') and 
  20783.             name = 'identity_support')
  20784.         begin
  20785.             alter table sysarticleupdates add identity_support bit default 0 NOT NULL
  20786.         end
  20787.  
  20788.     end
  20789.  
  20790.     -- Upgrade dbt->distbackuplsn
  20791.     -- Make sure the upgrade is done for 8.0 Beta 2 customers.
  20792.     if exists (select * from sysobjects where name = 'sysarticles') and
  20793.         not exists (select * from sysobjects where name = 'systranschemas')
  20794.     begin
  20795.         -- Force to get in even if the logreader is running.
  20796.         exec sp_replflush 
  20797.         exec sp_repldone @xactid = NULL, @xact_segno = NULL, @numtrans = 0,
  20798.             @time = 0, @reset = 0, @code = 1
  20799.         -- Unmark the connection as the logreader.
  20800.         exec sp_replflush
  20801.     end
  20802.  
  20803.     -- Create new tran tables if the db is enabled for tran publishing.
  20804.     if exists (select name from sysobjects where name='syspublications')
  20805.     begin
  20806.         exec dbo.sp_MScreate_pub_tables
  20807.     end
  20808.  
  20809.     /*
  20810.      * syspublications
  20811.     */
  20812.     if exists (select name from sysobjects where name='syspublications')
  20813.     begin
  20814.         if not exists (select * from syscolumns where id = Object_Id('syspublications') and name = 'ftp_password' and length = '1048')
  20815.         begin
  20816.             /*
  20817.              * syspublications ftp_password
  20818.              * no need to upgrade passwords since this column is new in 8.0.
  20819.             */
  20820.             declare @dbname sysname
  20821.             declare @cmptlevel tinyint
  20822.             set @dbname = db_name()
  20823.             select @cmptlevel = cmptlevel from master..sysdatabases where name = @dbname collate database_default
  20824.             if @cmptlevel < 70
  20825.             begin
  20826.                                 raiserror (15048, -1, -1, 70, 70, 70, 80)
  20827.             end
  20828.             else
  20829.             begin
  20830.                 exec( 'alter table syspublications alter column ftp_password nvarchar(524)' )
  20831.             end
  20832.         end
  20833.     end
  20834. end
  20835. go
  20836. exec dbo.sp_MS_marksystemobject sp_vupgrade_publisherdb
  20837. go
  20838.  
  20839. raiserror('Creating procedure sp_vupgrade_replmsdb', 0,1)
  20840. go
  20841. create procedure sp_vupgrade_replmsdb 
  20842. as
  20843. begin
  20844. /* 
  20845.  * Process schema and metadata changes specific to a msdb database. Updates datatype
  20846.  * mappings for heterogeneous replication.
  20847.  *
  20848.  * Setup version upgrade procedure call order:
  20849.  *    sp_vupgrade_replication -> sp_vupgrade_replmsdb (only called at distributors)
  20850. */
  20851.  
  20852.     set nocount on 
  20853.  
  20854.     declare @retcode int
  20855.             ,@profile_id int
  20856.             ,@table_name sysname
  20857.             ,@profile_name nvarchar(100)
  20858.             ,@profile_desc nvarchar(100)
  20859.  
  20860.     -- raiserror('sp_vupgrade_replmsdb', 0,1)
  20861.     
  20862.     -- Drop and regenerate agent parameters and associated values from system profiles.
  20863.     select @profile_id = 1
  20864.     while (@profile_id < 8)
  20865.     begin
  20866.  
  20867.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  20868.         if (@retcode = 1)
  20869.             return (1)
  20870.  
  20871.         exec @retcode = dbo.sp_generate_agent_parameter @profile_id
  20872.         if (@retcode = 1)
  20873.             return (1)
  20874.  
  20875.         select @profile_id = @profile_id + 1
  20876.  
  20877.     end
  20878.     
  20879.     declare hUserProfile CURSOR LOCAL FAST_FORWARD FOR
  20880.         select distinct profile_id from msdb..MSagent_profiles where profile_id >= 8 for read only   
  20881.     open hUserProfile 
  20882.     fetch hUserProfile into @profile_id
  20883.  
  20884.     while @@fetch_status <> -1
  20885.         begin
  20886.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id, @parameter_name = '-ReadBatchThreshold'
  20887.         if (@retcode = 1)
  20888.         begin
  20889.             close hUserProfile 
  20890.             deallocate hUserProfile 
  20891.                 return (1)
  20892.         end
  20893.  
  20894.         fetch hUserProfile into @profile_id
  20895.         end    
  20896.         close hUserProfile 
  20897.         deallocate hUserProfile 
  20898.  
  20899.     --
  20900.     -- Add 8.0 agent profiles
  20901.     --
  20902.  
  20903.     /* 
  20904.     ** Distribution agent : Synchronization Manager Profile
  20905.     */
  20906.     select @profile_id = NULL
  20907.         ,@profile_name = formatmessage(20550) -- Dist SyncMgr Profile
  20908.         ,@profile_desc = formatmessage(20551)
  20909.     select @profile_id = profile_id from msdb..MSagent_profiles 
  20910.         where agent_type = 3 and profile_name = @profile_name
  20911.     if (@profile_id is null)
  20912.     begin
  20913.         --
  20914.         -- Add profile
  20915.         --
  20916.         select @profile_id = NULL
  20917.  
  20918.         exec @retcode = dbo.sp_add_agent_profile
  20919.                 @profile_id = @profile_id OUT,
  20920.                 @profile_name = @profile_name,
  20921.                 @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  20922.                 @profile_type = 0,   -- 0-System, 1-Custom 
  20923.                 @description = @profile_desc,
  20924.                 @default = 0
  20925.         if (@retcode = 1 or @@ERROR <> 0)
  20926.             return (1)
  20927.     end
  20928.     else
  20929.     begin
  20930.         --
  20931.         -- Profile exists - drop the parameters for regeneration
  20932.         --
  20933.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  20934.         if (@retcode = 1)
  20935.             return (1)
  20936.     end
  20937.     exec @retcode = dbo.sp_generate_agent_parameter 
  20938.         @profile_id = 10,
  20939.         @real_profile_id = @profile_id
  20940.     if (@retcode = 1 or @@ERROR <> 0)
  20941.         return (1)
  20942.  
  20943.  
  20944.     -- Queue default profile
  20945.     select @profile_id = NULL
  20946.     select @profile_id = profile_id from msdb..MSagent_profiles 
  20947.         where agent_type = 9 and def_profile = 1
  20948.     if (@profile_id is null)
  20949.     begin
  20950.         --
  20951.         -- Add profile
  20952.         --
  20953.         select @profile_id = NULL
  20954.                 ,@profile_name = formatmessage(20545) -- Default QueueReader Profile
  20955.                 ,@profile_desc = formatmessage(20589)
  20956.  
  20957.         exec @retcode = dbo.sp_add_agent_profile
  20958.             @profile_id = @profile_id OUT,
  20959.             @profile_name = @profile_name,
  20960.             @agent_type = 9,
  20961.             @profile_type = 0, 
  20962.             @description = @profile_desc,
  20963.             @default = 1
  20964.         if (@retcode = 1 or @@ERROR <> 0)
  20965.             return (1)
  20966.     end
  20967.     else
  20968.     begin
  20969.         --
  20970.         -- Profile exists - drop the parameters for regeneration
  20971.         --
  20972.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  20973.         if (@retcode = 1)
  20974.             return (1)
  20975.     end
  20976.     exec @retcode = dbo.sp_generate_agent_parameter 
  20977.         @profile_id = 11,
  20978.         @real_profile_id = @profile_id
  20979.     if (@retcode = 1 or @@ERROR <> 0)
  20980.         return (1)
  20981.  
  20982.     --
  20983.     -- Add 'skip data consistency error' profile
  20984.     --
  20985.     select @profile_id = NULL
  20986.         ,@profile_name = formatmessage(20599) -- Default Distribution Profile
  20987.         ,@profile_desc = formatmessage(20600)
  20988.     select @profile_id = profile_id from msdb..MSagent_profiles 
  20989.         where agent_type = 3 and profile_name = @profile_name
  20990.     if (@profile_id is null)
  20991.     begin
  20992.         --
  20993.         -- Add profile
  20994.         --
  20995.         select @profile_id = NULL
  20996.  
  20997.         exec @retcode = dbo.sp_add_agent_profile
  20998.                 @profile_id = @profile_id OUT,
  20999.                 @profile_name = @profile_name,
  21000.                 @agent_type = 3,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21001.                 @profile_type = 0,   -- 0-System, 1-Custom 
  21002.                 @description = @profile_desc,
  21003.                 @default = 0
  21004.         if (@retcode = 1 or @@ERROR <> 0)
  21005.             return (1)
  21006.     end
  21007.     else
  21008.     begin
  21009.         --
  21010.         -- Profile exists - drop the parameters for regeneration
  21011.         --
  21012.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21013.         if (@retcode = 1)
  21014.             return (1)
  21015.     end
  21016.     exec @retcode = dbo.sp_generate_agent_parameter 
  21017.         @profile_id = 14,
  21018.         @real_profile_id = @profile_id
  21019.     if (@retcode = 1 or @@ERROR <> 0)
  21020.         return (1)
  21021.         
  21022.     /* 
  21023.     ** Merge agent : Non default profile for disconnected scenarios ( unreliable link ) 
  21024.     */
  21025.     set @profile_id = NULL
  21026.     set @profile_name = formatmessage(20548) -- Non-Default Merge Profile
  21027.     set @profile_desc = formatmessage(20549)
  21028.  
  21029.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21030.     if (@profile_id is null)
  21031.     begin
  21032.         exec @retcode = dbo.sp_add_agent_profile
  21033.             @profile_id = @profile_id OUT,
  21034.             @profile_name = @profile_name,
  21035.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21036.             @profile_type = 0,   -- 0-System, 1-Custom 
  21037.             @description = @profile_desc,
  21038.             @default = 0
  21039.     end
  21040.     else
  21041.     begin
  21042.         --
  21043.         -- Profile exists - drop the parameters for regeneration
  21044.         --
  21045.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21046.         if (@retcode = 1)
  21047.             return (1)
  21048.     end
  21049.  
  21050.     exec @retcode = dbo.sp_generate_agent_parameter 7, @profile_id
  21051.     if (@retcode = 1 or @@ERROR <> 0)
  21052.         return (1)
  21053.  
  21054.     /* 
  21055.     ** Merge agent : Non default profile for verbose histroy
  21056.     */
  21057.     set @profile_id = NULL
  21058.     set @profile_name = formatmessage(20546) -- Verbose Merge Profile
  21059.     set @profile_desc = formatmessage(20547)
  21060.  
  21061.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21062.     if (@profile_id is null)
  21063.     begin
  21064.         exec @retcode = dbo.sp_add_agent_profile
  21065.             @profile_id = @profile_id OUT,
  21066.             @profile_name = @profile_name,
  21067.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21068.             @profile_type = 0,   -- 0-System, 1-Custom 
  21069.             @description = @profile_desc,
  21070.             @default = 0
  21071.     end
  21072.     else
  21073.     begin
  21074.         --
  21075.         -- Profile exists - drop the parameters for regeneration
  21076.         --
  21077.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21078.         if (@retcode = 1)
  21079.             return (1)
  21080.     end
  21081.  
  21082.     exec @retcode = dbo.sp_generate_agent_parameter 8, @profile_id
  21083.     if (@retcode = 1 or @@ERROR <> 0)
  21084.         return (1)
  21085.  
  21086.     /* 
  21087.     ** Merge agent : Synchronization Manager Profile
  21088.     */
  21089.     set @profile_id = NULL
  21090.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  21091.     set @profile_desc = formatmessage(20551)
  21092.  
  21093.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21094.     if (@profile_id is null)
  21095.     begin
  21096.         exec @retcode = dbo.sp_add_agent_profile
  21097.             @profile_id = @profile_id OUT,
  21098.             @profile_name = @profile_name,
  21099.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21100.             @profile_type = 0,   -- 0-System, 1-Custom 
  21101.             @description = @profile_desc,
  21102.             @default = 0
  21103.     end
  21104.     else
  21105.     begin
  21106.         --
  21107.         -- Profile exists - drop the parameters for regeneration
  21108.         --
  21109.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21110.         if (@retcode = 1)
  21111.             return (1)
  21112.     end
  21113.  
  21114.     exec @retcode = dbo.sp_generate_agent_parameter 9, @profile_id
  21115.     if (@retcode = 1 or @@ERROR <> 0)
  21116.         return (1)
  21117.  
  21118.      /* 
  21119.     ** Merge agent : Rowcount Validation profile  
  21120.     */
  21121.     set @profile_id = NULL
  21122.     set @profile_name = formatmessage(21308) -- Rowcount Validation Profile
  21123.     set @profile_desc = formatmessage(21309) -- Rowcount Validation Profile Description
  21124.  
  21125.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21126.     if (@profile_id is null)
  21127.     begin
  21128.         exec @retcode = dbo.sp_add_agent_profile
  21129.             @profile_id = @profile_id OUT,
  21130.             @profile_name = @profile_name,
  21131.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21132.             @profile_type = 0,   -- 0-System, 1-Custom 
  21133.             @description = @profile_desc,
  21134.             @default = 0
  21135.     end
  21136.     else
  21137.     begin
  21138.         --
  21139.         -- Profile exists - drop the parameters for regeneration
  21140.         --
  21141.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21142.         if (@retcode = 1)
  21143.             return (1)
  21144.     end
  21145.  
  21146.     exec @retcode = dbo.sp_generate_agent_parameter 12, @profile_id
  21147.     if (@retcode = 1 or @@ERROR <> 0)
  21148.         return (1)
  21149.  
  21150.     /* 
  21151.     ** Merge agent : Rowcount & Checksum Validation profile  
  21152.     */
  21153.     set @profile_id = NULL
  21154.     set @profile_name = formatmessage(21310) -- Rowcount & Checksum Validation Profile
  21155.     set @profile_desc = formatmessage(21311) -- Rowcount & Checksum Validation Profile Description
  21156.     
  21157.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21158.     if (@profile_id is null)
  21159.     begin
  21160.         exec @retcode = dbo.sp_add_agent_profile
  21161.             @profile_id = @profile_id OUT,
  21162.             @profile_name = @profile_name,
  21163.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21164.             @profile_type = 0,   -- 0-System, 1-Custom 
  21165.             @description = @profile_desc,
  21166.             @default = 0
  21167.     end
  21168.     else
  21169.     begin
  21170.         --
  21171.         -- Profile exists - drop the parameters for regeneration
  21172.         --
  21173.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21174.         if (@retcode = 1)
  21175.             return (1)
  21176.     end
  21177.  
  21178.     exec @retcode = dbo.sp_generate_agent_parameter 13, @profile_id
  21179.     if (@retcode = 1 or @@ERROR <> 0)
  21180.         return (1)
  21181.  
  21182.     /* 
  21183.     ** Merge agent : High volume server-to-server profile
  21184.     */
  21185.     set @profile_id = NULL
  21186.     set @profile_name = formatmessage(20616) -- High volume server-to-server profile
  21187.     set @profile_desc = formatmessage(20617) -- High volume server-to-server profile Description
  21188.  
  21189.     select @profile_id = profile_id from msdb..MSagent_profiles where agent_type = 4 and profile_name = @profile_name
  21190.     if (@profile_id is null)
  21191.     begin
  21192.         exec @retcode = dbo.sp_add_agent_profile
  21193.             @profile_id = @profile_id OUT,
  21194.             @profile_name = @profile_name,
  21195.             @agent_type = 4,   -- 1-Snapshot, 2-Logreader, 3-Distribution, 4-Merge
  21196.             @profile_type = 0,   -- 0-System, 1-Custom 
  21197.             @description = @profile_desc,
  21198.             @default = 0
  21199.     end
  21200.     else
  21201.     begin
  21202.         --
  21203.         -- Profile exists - drop the parameters for regeneration
  21204.         --
  21205.         exec @retcode = dbo.sp_drop_agent_parameter @profile_id
  21206.         if (@retcode = 1)
  21207.             return (1)
  21208.     end
  21209.  
  21210.     exec @retcode = dbo.sp_generate_agent_parameter 15, @profile_id
  21211.     if (@retcode = 1 or @@ERROR <> 0)
  21212.         return (1)
  21213.  
  21214.     -- Add MSdatatype_mappings table and default mappings
  21215.     if not exists( select * from msdb..sysobjects where name = 'MSdatatype_mappings' 
  21216.         and xtype = 'U')
  21217.     begin
  21218.         create table msdb.dbo.MSdatatype_mappings 
  21219.         (
  21220.         dbms_name           sysname NOT NULL,
  21221.         sql_type            sysname NOT NULL,
  21222.         dest_type           sysname NOT NULL,
  21223.         dest_prec           int     NOT NULL,
  21224.         dest_create_params  int     NOT NULL,
  21225.         dest_nullable       bit     NOT NULL
  21226.         )
  21227.  
  21228.         -- MS Jet
  21229.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'binary', 255, 4, 1
  21230.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'varbinary', 255, 4, 1
  21231.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'binary' , 'image', 1073741824, 0, 1
  21232.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varbinary' , 'image', 1073741824, 0, 1
  21233.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'sql_variant' , 'longtext', 1073741824, 0, 1
  21234.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'varchar', 255, 4, 1
  21235.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'varchar' , 'longtext', 1073741824, 0, 1
  21236.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'nchar', 255, 4, 1
  21237.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nchar' , 'longtext', 1073741824, 0, 1
  21238.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'char', 255, 4, 1
  21239.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'char' , 'longtext', 1073741824, 0, 1
  21240.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'nchar varying', 255, 4, 1
  21241.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'nvarchar' , 'longtext', 1073741824, 0, 1
  21242.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'datetime' , 'datetime', 255, 0, 1
  21243.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smalldatetime' , 'datetime', 255, 0, 1
  21244.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'decimal' , 'decimal', 255, 3, 1
  21245.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'numeric' , 'decimal', 255, 3, 1
  21246.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'float' , 'float', 255, 0, 1
  21247.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'real' , 'real', 255, 0, 1
  21248.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'bigint' , 'decimal', 255, 0, 1
  21249.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'int' , 'int', 255, 0, 1
  21250.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallint' , 'smallint', 255, 0, 1
  21251.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'tinyint' , 'byte', 255, 0, 1
  21252.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'money' , 'currency', 255, 0, 1
  21253.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'smallmoney' , 'currency', 255, 0, 1
  21254.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'bit' , 'bit', 255, 0, 1
  21255.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'sysname' , 'nchar varying', 255, 4, 1
  21256.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'timestamp' , 'binary', 255, 4, 1
  21257.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'uniqueidentifier' , 'guid', 255, 0, 1
  21258.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'text' , 'longtext', 1073741824, 0, 1
  21259.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'ntext' , 'longtext', 1073741824, 0, 1
  21260.         exec dbo.sp_add_datatype_mapping 'MS Jet', 'image' , 'image', 1073741824, 0, 1
  21261.  
  21262.         -- Oracle
  21263.         exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'raw', 255, 4, 1
  21264.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'raw', 255, 4, 1
  21265.         exec dbo.sp_add_datatype_mapping 'Oracle', 'binary' , 'long raw', 2147483647, 0, 1
  21266.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varbinary' , 'long raw', 2147483647, 0, 1
  21267.         exec dbo.sp_add_datatype_mapping 'Oracle', 'sql_variant' , 'long', 2147483647, 0, 1
  21268.         --exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'char', 255, 4, 1
  21269.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'varchar2', 2000, 4, 1
  21270.         exec dbo.sp_add_datatype_mapping 'Oracle', 'varchar' , 'long', 2147483647, 0, 1
  21271.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'char', 255, 4, 1
  21272.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'varchar2', 2000, 4, 1
  21273.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nchar' , 'long', 2147483647, 0, 1
  21274.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'char', 255, 4, 1
  21275.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'varchar2', 2000, 4, 1
  21276.         exec dbo.sp_add_datatype_mapping 'Oracle', 'char' , 'long', 2147483647, 0, 1
  21277.         --exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'char', 255, 4, 1
  21278.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'varchar2', 2000, 4, 1
  21279.         exec dbo.sp_add_datatype_mapping 'Oracle', 'nvarchar' , 'long', 2147483647, 0, 1
  21280.         exec dbo.sp_add_datatype_mapping 'Oracle', 'datetime' , 'date', 255, 0, 1
  21281.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smalldatetime' , 'date', 255, 0, 1
  21282.         exec dbo.sp_add_datatype_mapping 'Oracle', 'decimal' , 'number', 255, 3, 1
  21283.         exec dbo.sp_add_datatype_mapping 'Oracle', 'numeric' , 'number', 255, 3, 1
  21284.         exec dbo.sp_add_datatype_mapping 'Oracle', 'float' , 'float', 255, 0, 1
  21285.         exec dbo.sp_add_datatype_mapping 'Oracle', 'real' , 'float', 255, 0, 1
  21286.         exec dbo.sp_add_datatype_mapping 'Oracle', 'bigint' , 'number', 255, 3, 1
  21287.         exec dbo.sp_add_datatype_mapping 'Oracle', 'int' , 'number', 255, 3, 1
  21288.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smallint' , 'number', 255, 3, 1
  21289.         exec dbo.sp_add_datatype_mapping 'Oracle', 'tinyint' , 'number', 255, 3, 1
  21290.         exec dbo.sp_add_datatype_mapping 'Oracle', 'money' , 'number', 255, 3, 1
  21291.         exec dbo.sp_add_datatype_mapping 'Oracle', 'smallmoney' , 'number', 255, 3, 1
  21292.         exec dbo.sp_add_datatype_mapping 'Oracle', 'bit' , 'number', 255, 3, 1
  21293.         exec dbo.sp_add_datatype_mapping 'Oracle', 'sysname' , 'char', 255, 4, 1
  21294.         exec dbo.sp_add_datatype_mapping 'Oracle', 'timestamp' , 'raw', 255, 4, 1
  21295.         exec dbo.sp_add_datatype_mapping 'Oracle', 'uniqueidentifier' , 'char', 255, 4, 1
  21296.         exec dbo.sp_add_datatype_mapping 'Oracle', 'text' , 'long', 2147483647, 0, 1
  21297.         exec dbo.sp_add_datatype_mapping 'Oracle', 'ntext' , 'long', 2147483647, 0, 1
  21298.         exec dbo.sp_add_datatype_mapping 'Oracle', 'image' , 'long raw', 2147483647, 0, 1
  21299.  
  21300.         -- MS SSCE
  21301.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'binary' , 'binary', 255, 4, 1
  21302.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varbinary' , 'varbinary', 255, 4, 1
  21303.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'binary' , 'image', 1073741824, 0, 1
  21304.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varbinary' , 'image', 1073741824, 0, 1
  21305.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'sql_variant' , 'ntext', 1073741824, 0, 1
  21306.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varchar' , 'national char varying', 255, 4, 1
  21307.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'varchar' , 'ntext', 1073741824, 0, 1
  21308.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nchar' , 'nchar', 255, 4, 1
  21309.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nchar' , 'ntext', 1073741824, 0, 1
  21310.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'char' , 'nchar', 255, 4, 1
  21311.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'char' , 'ntext', 1073741824, 0, 1
  21312.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nvarchar' , 'national char varying', 255, 4, 1
  21313.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'nvarchar' , 'ntext', 1073741824, 0, 1
  21314.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'datetime' , 'datetime', 255, 0, 1
  21315.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smalldatetime' , 'datetime', 255, 0, 1
  21316.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'decimal' , 'numeric', 255, 3, 1
  21317.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'numeric' , 'numeric', 255, 3, 1
  21318.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'float' , 'float', 255, 0, 1
  21319.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'real' , 'real', 255, 0, 1
  21320.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'bigint' , 'bigint', 255, 0, 1
  21321.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'int' , 'int', 255, 0, 1
  21322.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smallint' , 'smallint', 255, 0, 1
  21323.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'tinyint' , 'tinyint', 255, 0, 1
  21324.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'money' , 'money', 255, 0, 1
  21325.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'smallmoney' , 'money', 255, 0, 1
  21326.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'bit' , 'bit', 255, 0, 1
  21327.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'sysname' , 'national char varying', 255, 4, 1
  21328.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'timestamp' , 'binary', 255, 4, 1
  21329.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'uniqueidentifier' , 'uniqueidentifier', 255, 0, 1
  21330.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'text' , 'ntext', 1073741824, 0, 1
  21331.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'ntext' , 'ntext', 1073741824, 0, 1
  21332.         exec dbo.sp_add_datatype_mapping 'MS SSCE', 'image' , 'image', 1073741824, 0, 1
  21333.  
  21334.         --DB2/400
  21335.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'bit', 'SMALLINT', 1,  0, 1
  21336.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'tinyint', 'SMALLINT', 1, 0, 1
  21337.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smallint', 'SMALLINT', 5, 0, 1
  21338.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'int', 'INT', 10, 0, 1
  21339.  
  21340.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'char', 'CHAR', 8000, 4, 1
  21341.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'varchar', 'VARCHAR', 8000, 4, 1
  21342.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  21343.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'datetime', 'TIMESTAMP', 26, 0, 1
  21344.  
  21345.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'real', 'REAL', 24, 0, 1
  21346.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'decimal', 'DECIMAL', 31, 3, 1
  21347.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'double precision', 'DOUBLE', 53, 0, 1
  21348.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'float', 'FLOAT', 53, 0, 1
  21349.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'numeric', 'NUMERIC', 31, 3, 1
  21350.  
  21351.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'smallmoney', 'DECIMAL', 10, 3, 1
  21352.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'money', 'DECIMAL', 19, 3, 1
  21353.  
  21354.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'varbinary', 'VARCHAR () FOR BIT DATA', 8000, 4, 1
  21355.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'binary', 'CHAR () FOR BIT DATA', 8000, 4, 1
  21356.  
  21357.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  21358.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'uniqueidentifier', 'CHAR', 38, 4, 1
  21359.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'image', 'VARCHAR () FOR BIT DATA', 32739, 4, 1
  21360.         exec dbo.sp_add_datatype_mapping 'DB2/400', 'text', 'VARCHAR', 32739, 4, 1
  21361.  
  21362.         --DB2/MVS
  21363.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'bit', 'SMALLINT', 1,  0, 1
  21364.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'tinyint', 'SMALLINT', 1, 0, 1
  21365.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smallint', 'SMALLINT', 5, 0, 1
  21366.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'int', 'INT', 10, 0, 1
  21367.  
  21368.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'char', 'CHAR', 254, 4, 1
  21369.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'varchar', 'VARCHAR', 4045, 4, 1
  21370.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'char', 'VARCHAR', 4045, 4, 1
  21371.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  21372.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'datetime', 'TIMESTAMP', 26, 0, 1
  21373.  
  21374.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'real', 'REAL', 24, 0, 1
  21375.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'decimal', 'DECIMAL', 31, 3, 1
  21376.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'double precision', 'DOUBLE', 53, 0, 1
  21377.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'float', 'FLOAT', 53, 0, 1
  21378.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'numeric', 'NUMERIC', 31, 3, 1
  21379.  
  21380.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'smallmoney', 'DECIMAL', 10, 3, 1
  21381.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'money', 'DECIMAL', 19, 3, 1
  21382.  
  21383.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'varbinary', 'VARCHAR () FOR BIT DATA', 4045, 4, 1
  21384.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  21385.  
  21386.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  21387.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'uniqueidentifier', 'CHAR', 38, 4, 1
  21388.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'image', 'VARCHAR () FOR BIT DATA', 4045, 4, 1
  21389.         exec dbo.sp_add_datatype_mapping 'DB2/MVS', 'text', 'VARCHAR', 4045, 4, 1
  21390.  
  21391.         --DB2/NT
  21392.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'bit', 'SMALLINT', 1,  0, 1
  21393.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'tinyint', 'SMALLINT', 1, 0, 1
  21394.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smallint', 'SMALLINT', 5, 0, 1
  21395.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'int', 'INT', 10, 0, 1
  21396.  
  21397.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'char', 'CHAR', 254, 4, 1
  21398.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'varchar', 'VARCHAR', 4000, 4, 1
  21399.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'char', 'VARCHAR', 4000, 4, 1
  21400.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  21401.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'datetime', 'TIMESTAMP', 26, 0, 1
  21402.  
  21403.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'real', 'REAL', 24, 0, 1
  21404.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'decimal', 'DECIMAL', 31, 3, 1
  21405.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'double precision', 'DOUBLE', 53, 0, 1
  21406.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'float', 'FLOAT', 53, 0, 1
  21407.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'numeric', 'NUMERIC', 31, 3, 1
  21408.  
  21409.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'smallmoney', 'DECIMAL', 10, 3, 1
  21410.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'money', 'DECIMAL', 19, 3, 1
  21411.  
  21412.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'varbinary', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  21413.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  21414.  
  21415.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  21416.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'uniqueidentifier', 'CHAR', 38, 4, 1
  21417.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'image', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  21418.         exec dbo.sp_add_datatype_mapping 'DB2/NT', 'text', 'VARCHAR', 4000, 4, 1
  21419.  
  21420.  
  21421.         --DB2/6000
  21422.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'bit', 'SMALLINT', 1,  0, 1
  21423.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'tinyint', 'SMALLINT', 1, 0, 1
  21424.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smallint', 'SMALLINT', 5, 0, 1
  21425.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'int', 'INT', 10, 0, 1
  21426.  
  21427.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'char', 'CHAR', 254, 4, 1
  21428.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'varchar', 'VARCHAR', 4000, 4, 1
  21429.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'char', 'VARCHAR', 4000, 4, 1
  21430.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smalldatetime', 'TIMESTAMP', 26, 0, 1
  21431.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'datetime', 'TIMESTAMP', 26, 0, 1
  21432.  
  21433.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'real', 'REAL', 24, 0, 1
  21434.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'decimal', 'DECIMAL', 31, 3, 1
  21435.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'double precision', 'DOUBLE', 53, 0, 1
  21436.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'float', 'FLOAT', 53, 0, 1
  21437.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'numeric', 'NUMERIC', 31, 3, 1
  21438.  
  21439.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'smallmoney', 'DECIMAL', 10, 3, 1
  21440.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'money', 'DECIMAL', 19, 3, 1
  21441.  
  21442.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'varbinary', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  21443.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'binary', 'CHAR () FOR BIT DATA', 254, 4, 1
  21444.  
  21445.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'timestamp', 'CHAR () FOR BIT DATA', 8, 4, 1
  21446.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'uniqueidentifier', 'CHAR', 38, 4, 1
  21447.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'image', 'VARCHAR () FOR BIT DATA', 4000, 4, 1
  21448.         exec dbo.sp_add_datatype_mapping 'DB2/6000', 'text', 'VARCHAR', 4000, 4, 1
  21449.  
  21450.     end
  21451.  
  21452.     /*
  21453.      * New indexes added starting with 7.0 sp1
  21454.     */
  21455.  
  21456.     --    MSdistpublishers
  21457.     select @table_name = N'MSdistpublishers'
  21458.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistpublishers' ) 
  21459.     BEGIN
  21460.         IF EXISTS ( SELECT name
  21461.             FROM msdb.dbo.MSdistpublishers
  21462.             GROUP BY name 
  21463.             HAVING COUNT(*) > 1 )
  21464.             RAISERROR (21203, 10, 19, @table_name)
  21465.         ELSE
  21466.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistpublishers' AND
  21467.                 id = OBJECT_ID('msdb.dbo.MSdistpublishers') )
  21468.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistpublishers ON msdb.dbo.MSdistpublishers(name)
  21469.  
  21470.     END
  21471.     
  21472.     --    MSdistributiondbs
  21473.     SELECT @table_name = N'MSdistributiondbs'
  21474.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistributiondbs' )
  21475.     BEGIN
  21476.         IF EXISTS ( SELECT name
  21477.             FROM msdb.dbo.MSdistributiondbs
  21478.             GROUP BY name 
  21479.             HAVING COUNT(*) > 1 )
  21480.             RAISERROR (21203, 10, 20, @table_name)            
  21481.         ELSE                
  21482.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistributiondbs' AND
  21483.                 id = OBJECT_ID('msdb.dbo.MSdistributiondbs') )
  21484.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributiondbs ON msdb.dbo.MSdistributiondbs(name)
  21485.     END
  21486.     
  21487.     --    MSdistributor
  21488.     SELECT @table_name = N'MSdistributor'
  21489.     IF EXISTS ( SELECT * FROM msdb.dbo.sysobjects WHERE name = 'MSdistributor' )
  21490.     BEGIN
  21491.         IF EXISTS ( SELECT property
  21492.             FROM msdb.dbo.MSdistributor
  21493.             GROUP BY property 
  21494.             HAVING COUNT(*) > 1 )
  21495.             RAISERROR (21203, 10, 21, @table_name)            
  21496.         ELSE                    
  21497.             IF NOT EXISTS ( SELECT * FROM msdb.dbo.sysindexes WHERE name = 'uc1MSdistributor' AND
  21498.                 id = OBJECT_ID('msdb.dbo.MSdistributor') )
  21499.                 CREATE UNIQUE CLUSTERED INDEX uc1MSdistributor ON msdb.dbo.MSdistributor(property)
  21500.     END    
  21501.  
  21502.     /* 
  21503.      * Upgrade replication passwords in msdb database.
  21504.     */
  21505.     begin transaction
  21506.     /*
  21507.      * MSdistpublishers
  21508.     */
  21509.     if exists (select name from msdb.dbo.sysobjects where name='MSdistpublishers')
  21510.     begin
  21511.         if not exists (select * from msdb.dbo.syscolumns where id = Object_Id('msdb.dbo.MSdistpublishers') and name = 'password' and length = '1048')
  21512.         begin
  21513.             /*
  21514.              * alter password column from sysname to nvarchar(524)
  21515.             */
  21516.  
  21517.             alter table msdb.dbo.MSdistpublishers alter column password nvarchar(524)
  21518.         end
  21519.  
  21520.         /*
  21521.          * convert all the passwords to new encryption
  21522.          */
  21523.         declare @password nvarchar(524)
  21524.         declare cur_MSdistpublishers CURSOR LOCAL FORWARD_ONLY for 
  21525.             select password
  21526.             from msdb.dbo.MSdistpublishers
  21527.             for update of password
  21528.             
  21529.         open cur_MSdistpublishers
  21530.         fetch next from cur_MSdistpublishers into @password
  21531.         while ( @@fetch_status <> -1 )
  21532.         begin
  21533.             EXEC @retcode = master.dbo.xp_repl_convert_encrypt @password OUTPUT
  21534.             IF @@error <> 0 OR @retcode <> 0
  21535.             begin
  21536.                 rollback transaction
  21537.                 return 1
  21538.             end
  21539.  
  21540.             update msdb.dbo.MSdistpublishers
  21541.             set password=@password
  21542.             where current of cur_MSdistpublishers
  21543.  
  21544.             fetch next from cur_MSdistpublishers into @password
  21545.         end
  21546.     end
  21547.     commit transaction
  21548.  
  21549.     return (0)
  21550. end
  21551. go
  21552. exec dbo.sp_MS_marksystemobject sp_vupgrade_replmsdb
  21553. go
  21554.  
  21555. raiserror('Creating procedure sp_restoredbreplication', 0,1)
  21556. go
  21557.  
  21558. create procedure sp_restoredbreplication ( @srv_orig sysname, @db_orig sysname
  21559. ,@keep_replication int = 0 -- Make it int so that we can expand later.
  21560.  )
  21561. as 
  21562. /*
  21563.  * used by restore process to strip out replication settings if restoring to non-originating
  21564.  * server/db or system otherwise not capable of keeping replication working
  21565.  * WARNING : procs called here run internal to server and must be owner qualified
  21566. */
  21567. begin
  21568.  
  21569.     set nocount on
  21570.  
  21571.     -- db bits
  21572.     declare @db_tranbit int
  21573.     declare @db_mergbit int
  21574.     declare @db_distbit int
  21575.     select @db_tranbit = 1, @db_mergbit = 4, @db_distbit = 16
  21576.  
  21577.     declare @repl_installed bit -- repl procs installed flag
  21578.     declare @remove_repl bit    -- remove replication flag ; remove on true (1)
  21579.     declare @restoreoverride int
  21580.     declare @db_curr sysname
  21581.     DECLARE @retcode int
  21582.     DECLARE @proc nvarchar(255)
  21583.  
  21584.     -- Fixup lsns for dist db if needed
  21585.     -- This is to make sure that after the restore, the lsns are equal to or larger than
  21586.     -- the ones that have been sent to the publishers before the restore.
  21587.     -- reuse the procedures used by backup.
  21588.     exec @retcode = dbo.sp_MSrepl_backup_start
  21589.     if @retcode <> 0 or @@error <> 0
  21590.         return 0
  21591.     exec @retcode = dbo.sp_MSrepl_backup_complete
  21592.     if @retcode <> 0 or @@error <> 0
  21593.         return 0
  21594.  
  21595.     -- Support override of replication remove on attach and restore
  21596.     declare @instance sysname
  21597.     declare @regkey nvarchar(260)
  21598.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  21599.     select @regkey = 'SOFTWARE\Microsoft\'
  21600.     -- default installation
  21601.     if @instance is null
  21602.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  21603.     else
  21604.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  21605.  
  21606.     SELECT @restoreoverride = 0 -- assume normal remove behavior
  21607.     SELECT @proc = 'master.dbo.xp_regread '
  21608.     EXECUTE @retcode = @proc    'HKEY_LOCAL_MACHINE', 
  21609.                                 @regkey,
  21610.                                 'RestoreOverride',
  21611.                                 @param = @restoreoverride OUTPUT,
  21612.                                 @no_output = 'no_output'
  21613.  
  21614.     if ( @@error = 0 ) and ( @retcode = 0 )
  21615.     begin
  21616.         -- ReplRestoreOverride = 1 = user elects to take no cleanup on restore or attach
  21617.         if ( isnull( @restoreoverride, 0 ) = 1 )
  21618.             return(0)
  21619.     end
  21620.     
  21621.         
  21622.     select @remove_repl = 0, @repl_installed = 1 
  21623.  
  21624.     select @db_curr = db_name() 
  21625.  
  21626.     -- check server has replication installed; if not, we cannot remove replication; this should be benign
  21627.     if not exists ( select * from master..MSreplication_options 
  21628.                         where optname = 'transactional' 
  21629.                            or optname = 'merge' )
  21630.         select @repl_installed = 0
  21631.  
  21632.     -- check restore to same server/db backed up
  21633.     if (( UPPER(@srv_orig) <> UPPER(@@SERVERNAME) ) or ( @db_orig <> @db_curr )) and 
  21634.         @keep_replication = 0
  21635.         select @remove_repl = 1
  21636.  
  21637.     -- even it is the same server/db, if it is enabled for neither merge nor tran, we will do rmove_repl.
  21638.     
  21639. --    if not exists (select * from master..sysdatabases where name = @db_curr collate database_default and category & @db_tranbit = @db_tranbit )
  21640. --        and not exists (select * from master..sysdatabases where name = @db_curr collate database_default and category & @db_mergbit = @db_mergbit )
  21641. --        select @remove_repl = 1        
  21642.     -- in order to comply with BOL on restoring subscriber databases, this code segment has to go. 
  21643.  
  21644.     -- upgrade repl schema to latest version if it is restore of earlier database version (e.g. SQL70 backup)
  21645.     if ( exists( select * from sysobjects where name = N'syspublications' ) -- we think this is a tran pub db
  21646.             and not exists ( select * from sysobjects where name = N'sysextendedarticlesview' ) )
  21647.         or
  21648.        ( exists( select * from sysobjects where name = N'sysmergepublications' ) -- we think this is a merge pub db
  21649.             and not exists ( select * from sysobjects where name = N'sysmergeextendedarticlesview' ) )
  21650.     begin
  21651.         exec dbo.sp_vupgrade_publisherdb @ver_old = 999, @ver_retention = 999 -- retention and old version not relevant on restore
  21652.  
  21653.         -- update subscription tables schema only -- skip any recompile of procs, views, etc. -- we will just drop them after restore
  21654.         exec dbo.sp_vupgrade_MSsubscription_properties
  21655.         exec dbo.sp_vupgrade_subscription_tables
  21656.         exec dbo.sp_vupgrade_mergetables @skip_procgen = 1
  21657.  
  21658.     end
  21659.  
  21660.     -- subscribing dbs are assumed ok
  21661.     -- distribution dbs are assumed ok
  21662.  
  21663.     -- publishing db check : transactional : requires coordinated restore of dist db - no way to check
  21664.     if ( 
  21665.             exists( select * from sysobjects where name = 'syspublications' )
  21666.             -- exists( select * from syspublications ) 
  21667.             and not exists( select * from master..sysdatabases 
  21668.                 where name = @db_curr collate database_default and category & @db_tranbit = @db_tranbit )
  21669.         )
  21670.     begin
  21671.         -- publications exist in db, but db on server is not published; 
  21672.         -- unpublish the db, ignoring distributor cleanup
  21673.  
  21674.         update master.dbo.sysdatabases set category = category | @db_tranbit where name = @db_curr collate database_default
  21675.         exec dbo.sp_MSpublishdb 'false', 1
  21676.         update master.dbo.sysdatabases set category = category & ~@db_tranbit where name = @db_curr collate database_default
  21677.  
  21678.         -- we've already brute force stripped replication from the db, 
  21679.         -- don't call sp_removedbreplication at proc exit
  21680.     end
  21681.  
  21682.     if ( @repl_installed = 1 ) and ( @remove_repl = 1 ) 
  21683.         exec dbo.sp_removedbreplication @db_curr
  21684.  
  21685.  
  21686. end
  21687. go
  21688.  
  21689. exec dbo.sp_MS_marksystemobject sp_restoredbreplication
  21690. go
  21691.  
  21692. raiserror('Creating procedure sp_MSget_publisher_rpc', 0,1)
  21693. GO
  21694.  
  21695. CREATE PROCEDURE sp_MSget_publisher_rpc
  21696.         @trigger_id int,
  21697.         @connect_string nvarchar(2000) output
  21698.     AS
  21699.  
  21700.     SET NOCOUNT ON
  21701.     
  21702.     declare @publisher sysname
  21703.     declare @publisher_db sysname
  21704.     declare @login sysname
  21705.     declare @password nvarchar(524)
  21706.     declare @security_mode int
  21707.     declare @object_id int
  21708.     declare @retcode int
  21709.  
  21710.     -- Make sure this proc is called from the trigger.
  21711.     -- Better to use object_id if owner name is passed in.
  21712.     if trigger_nestlevel(@trigger_id) = 0
  21713.     begin
  21714.         raiserror(14126, 16, -1)
  21715.         return (1) -- current user does not have insert permission to underlying table
  21716.     end
  21717.  
  21718.     -- Get security from property table, if nothing find, the rpc will fail.
  21719.     IF EXISTS (select * from sysobjects where name = 'MSsubscription_properties' and type = 'U')
  21720.     begin
  21721.         select @login = publisher_login,
  21722.             @password = publisher_password,
  21723.             @security_mode = publisher_security_mode,
  21724.             @publisher = o.publisher,
  21725.             @publisher_db = o.publisher_db
  21726.          from MSsubscription_properties p, MSreplication_objects o
  21727.         where o.object_name = object_name(@trigger_id) 
  21728.         and UPPER(p.publisher) = UPPER(o.publisher)
  21729.         and p.publisher_db = p.publisher_db
  21730.         and p.publication = o.publication
  21731.  
  21732.         EXEC @retcode = master.dbo.xp_repl_help_connect @password OUTPUT
  21733.         IF @@error <> 0 OR @retcode <> 0
  21734.             return 1
  21735.  
  21736.     end
  21737.     else
  21738.     begin
  21739.         -- RPC security info invalid
  21740.         raiserror(21079, 16, -1)
  21741.         return(1)
  21742.     end
  21743.     
  21744.     if @security_mode = 2 -- 2 = use sysservers
  21745.     begin
  21746.         select @connect_string = null
  21747.     end
  21748.     else
  21749.     begin
  21750.         if @login is null
  21751.         begin
  21752.             -- RPC security info invalid
  21753.             raiserror(21079, 16, -1)
  21754.             return(1)
  21755.         end
  21756.  
  21757.         if @password is null
  21758.             select @password = N''
  21759.         -- Names containing space in connection string is automatically enabled.
  21760.         -- [] and ' are not recoginized by opendatasource
  21761.         -- Note ';' in names in connection string will mess things up.
  21762.         select @connect_string = 'SERVER=' + @publisher + ';UID=' + 
  21763.             @login + ';PWD=' + @password + ';'
  21764.     end
  21765. GO
  21766. exec dbo.sp_MS_marksystemobject sp_MSget_publisher_rpc
  21767. go
  21768.  
  21769. raiserror('Creating procedure sp_link_publication', 0,1)
  21770. GO
  21771.  
  21772. CREATE PROCEDURE sp_link_publication (
  21773.     @publisher      sysname,            -- publishing server name
  21774.     @publisher_db   sysname,            -- publishing database name. If NULL then same as current db
  21775.     @publication    sysname,            -- publication name
  21776.     @security_mode  int,                -- 0 = standard; 2 = static linked server entry
  21777.     @login            sysname = NULL,
  21778.     @password        sysname = NULL,
  21779.     @distributor    sysname = NULL
  21780. )
  21781. AS
  21782. BEGIN
  21783.     set nocount on
  21784.     declare @retcode int
  21785.     declare @enc_password nvarchar(524)
  21786.     
  21787.     --  Security Check
  21788.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  21789.     IF @@ERROR <> 0 or @retcode <> 0
  21790.     RETURN(1)
  21791.  
  21792.     -- Parameter check: @security_mode
  21793.     if @security_mode <> 0 and @security_mode <> 2
  21794.     begin
  21795.         RAISERROR(21055, 16, -1, '@security_mode','sp_link_publication')
  21796.         RETURN (1)
  21797.     end
  21798.  
  21799.     if @security_mode = 2 and not exists (select * from master..sysservers where
  21800.         UPPER(srvname) = UPPER(@publisher) collate database_default)
  21801.     begin
  21802.         RAISERROR(20620, 16, -1, @publisher)
  21803.         RETURN (1)
  21804.     end
  21805.  
  21806.     IF @password = N''
  21807.         select @password = NULL
  21808.  
  21809.     /* 
  21810.     ** Check to see if MSsubscription_properties table exists.
  21811.     ** If not, create it.
  21812.     */
  21813.     exec @retcode = dbo.sp_MScreate_sub_tables
  21814.     IF @@ERROR <> 0 or @retcode <> 0
  21815.         return 1
  21816.  
  21817.     -- Encrypt the password
  21818.     set @enc_password = @password
  21819.     EXEC @retcode = master.dbo.xp_repl_encrypt @enc_password OUTPUT
  21820.     IF @@error <> 0 OR @retcode <> 0
  21821.         return 1
  21822.  
  21823.     IF NOT EXISTS (select * from MSsubscription_properties 
  21824.             where UPPER(publisher) = UPPER(@publisher)
  21825.                 and publisher_db =  @publisher_db
  21826.                 and publication = @publication) 
  21827.     BEGIN
  21828.         INSERT INTO MSsubscription_properties 
  21829.             (publisher, publisher_db, publication, publication_type, 
  21830.              publisher_login,publisher_password, publisher_security_mode, 
  21831.              distributor, distributor_login, distributor_password, 
  21832.              distributor_security_mode)
  21833.         values (@publisher, @publisher_db, @publication, 0,    @login, @enc_password, 
  21834.             @security_mode, @distributor, NULL, NULL, 1)
  21835.     END
  21836.     ELSE
  21837.     BEGIN
  21838.         update MSsubscription_properties set
  21839.             publisher_login = @login,
  21840.             publisher_password = @enc_password,
  21841.             publisher_security_mode = @security_mode,
  21842.             distributor = isnull(@distributor, distributor)
  21843.             where UPPER(publisher) = UPPER(@publisher)
  21844.                 and publisher_db =  @publisher_db
  21845.                 and publication = @publication
  21846.     END
  21847. END
  21848. go
  21849.  
  21850. exec dbo.sp_MS_marksystemobject sp_link_publication
  21851. go
  21852.  
  21853. -- This proc is invoked on subscriber.
  21854. raiserror('Creating procedure sp_MSreset_queue', 0,1)
  21855. GO
  21856. CREATE PROCEDURE sp_MSreset_queue (
  21857.     @publisher      sysname,                    -- publishing server name
  21858.     @publisher_db   sysname,                    -- publishing database name. 
  21859.     @publication    sysname,                    -- publication name,
  21860.     @artid         int)
  21861. as
  21862. begin
  21863.     declare @subserver sysname
  21864.             ,@subdbname sysname
  21865.             ,@queue_id  sysname
  21866.             ,@update_mode int
  21867.             ,@retcode smallint
  21868.             ,@vbartid varbinary(20)
  21869.             ,@queue_server sysname
  21870.  
  21871.     set nocount on
  21872.  
  21873.     select     @subserver = @@servername, 
  21874.             @subdbname = db_name(),
  21875.             @update_mode = update_mode, 
  21876.             @queue_id = queue_id,
  21877.             @queue_server = queue_server
  21878.     from MSsubscription_agents
  21879.         where UPPER(publisher) = UPPER(@publisher)
  21880.             and publisher_db =  @publisher_db
  21881.             and publication = @publication
  21882.  
  21883.     if (@update_mode in (2,3))
  21884.     begin
  21885.         --
  21886.         -- MSMQ processing
  21887.         -- prefix the queue_id with queue server in direct format
  21888.         -- and then perform the queue reset
  21889.         --                        
  21890.         select @queue_id = N'DIRECT=OS:' + @queue_server + N'\PRIVATE$\' + @queue_id
  21891.         
  21892.         begin distributed tran
  21893.         exec @retcode = master.dbo.xp_resetqueue @queue_id, @subserver, 
  21894.                             @subdbname, @publication, @artid
  21895.         if (@retcode != 0 or @@error != 0)
  21896.         begin
  21897.             if (@@trancount > 0)
  21898.                 rollback tran
  21899.             return (1)    
  21900.         end
  21901.     end
  21902.     else if (@update_mode in (4,5))
  21903.     begin
  21904.         begin tran
  21905.         
  21906.         select @retcode = 0
  21907.         if (exists (select * from sysobjects 
  21908.             where name = 'MSreplication_queue'))
  21909.         begin
  21910.             --
  21911.             -- Strictly speaking we do no need
  21912.             -- to delete but, makes it easy for
  21913.             -- the queue reader agent
  21914.             -- Do not delete any reset messages
  21915.             --
  21916.             delete dbo.MSreplication_queue
  21917.                 where publisher = UPPER(@publisher)
  21918.                 and publisher_db =  @publisher_db
  21919.                 and publication = @publication
  21920.                 and tranid != N'sub-reset'
  21921.         end
  21922.         else
  21923.         begin
  21924.             --
  21925.             -- first queue subscription is being initialized
  21926.             -- create queue if necessary
  21927.             --
  21928.             exec @retcode = sp_MScreate_sub_tables
  21929.                 @tran_sub_table = 0,
  21930.                 @property_table = 0,
  21931.                 @sqlqueue_table = 1
  21932.         end
  21933.  
  21934.         --
  21935.         -- for subscription reinitialization we
  21936.         -- need to insert a RESYNC command message
  21937.         --
  21938.         select @vbartid = cast(@artid as varbinary(20))
  21939.         insert into dbo.MSreplication_queue (publisher, publisher_db,
  21940.             publication,tranid, commandtype, data, datalen)
  21941.         values (UPPER(@publisher), @publisher_db, 
  21942.             @publication, N'sub-reset', 2, @vbartid, datalength(@vbartid))
  21943.  
  21944.         if ((@@error != 0) or (@retcode != 0))
  21945.         begin
  21946.             if (@@trancount > 0)
  21947.                 rollback tran
  21948.             return (1)    
  21949.         end
  21950.     end
  21951.  
  21952.     commit tran
  21953.     return 0
  21954. end            
  21955. GO
  21956. exec dbo.sp_MS_marksystemobject sp_MSreset_queue
  21957. go
  21958. grant execute on dbo.sp_MSreset_queue to public
  21959. go
  21960.  
  21961. --
  21962. -- This proc is invoked on publisher, for resetting
  21963. -- the queued_reinit flag for a given subscription
  21964. -- 
  21965. raiserror('Creating procedure sp_MSreset_queued_reinit', 0,1)
  21966. GO
  21967. CREATE PROCEDURE sp_MSreset_queued_reinit (
  21968.     @subscriber      sysname,                    -- subscriber server name
  21969.     @subscriber_db   sysname,                    -- subscribing database name. 
  21970.     @artid    int)                                   -- article id
  21971. as
  21972. begin
  21973.     set nocount on
  21974.     declare @srvid int
  21975.     
  21976.     select @srvid = srvid from master.dbo.sysservers where UPPER(srvname) = UPPER(@subscriber) collate database_default
  21977.     
  21978.     update dbo.syssubscriptions
  21979.     set queued_reinit = 0
  21980.     where 
  21981.         artid = @artid 
  21982.         and srvid = @srvid
  21983.         and dest_db = @subscriber_db
  21984.     if (@@error != 0)
  21985.         return 1
  21986.  
  21987.     -- all done
  21988.     return 0
  21989. end            
  21990. GO
  21991. exec dbo.sp_MS_marksystemobject sp_MSreset_queued_reinit
  21992. go
  21993. grant execute on dbo.sp_MSreset_queued_reinit to public
  21994. go
  21995.  
  21996. raiserror('Creating procedure sp_MSinit_subscription_agent', 0,1)
  21997. GO
  21998.  
  21999. -- This proc is called by distribution agent.
  22000. CREATE PROCEDURE sp_MSinit_subscription_agent
  22001.     @publisher      sysname,                    -- publishing server name
  22002.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22003.     @publication    sysname,                    -- publication name,
  22004.     @subscription_type int
  22005. AS
  22006.     set nocount on
  22007.     declare @retcode int
  22008.     declare @login_time datetime
  22009.  
  22010.     --  Security Check
  22011.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  22012.     IF @@ERROR <> 0 or @retcode <> 0
  22013.     RETURN(1)
  22014.  
  22015.     -- For non independent agent publications
  22016.     if @publication is null or @publication = ''
  22017.         set @publication = 'ALL'
  22018.     
  22019.       select @login_time = login_time from master..sysprocesses where spid = @@spid
  22020.  
  22021.     if not exists (select * from MSsubscription_agents where
  22022.             UPPER(publisher) = UPPER(@publisher)
  22023.             and publisher_db =  @publisher_db
  22024.             and publication = @publication
  22025.             and subscription_type = @subscription_type)
  22026.     begin
  22027.         INSERT INTO MSsubscription_agents
  22028.             (publisher, publisher_db, publication, subscription_type,
  22029.              queue_id, update_mode, failover_mode, spid, login_time )
  22030.         values (@publisher, @publisher_db, @publication, @subscription_type, 
  22031.             null, 1, 0, @@spid, @login_time)
  22032.     end
  22033.     else
  22034.     begin
  22035.         -- It is possible that 2 instance of the distribution agent do this update at 
  22036.         -- the same time. One will fail later at the instance check at the distributor
  22037.         -- side. We no longer use the spid and login_time column anywhere else. 
  22038.         update MSsubscription_agents set      
  22039.             spid = @@spid,
  22040.             login_time = @login_time
  22041.             where UPPER(publisher) = UPPER(@publisher)
  22042.                 and publisher_db =  @publisher_db
  22043.                 and publication = @publication
  22044.                 and subscription_type = @subscription_type
  22045.     end
  22046. go
  22047.  
  22048. exec dbo.sp_MS_marksystemobject sp_MSinit_subscription_agent
  22049. go
  22050. grant execute on dbo.sp_MSinit_subscription_agent to public
  22051. go
  22052.  
  22053. raiserror('Creating procedure sp_MSupdatelastsyncinfo', 0,1)
  22054. GO
  22055.  
  22056. -- This proc is called by distribution agent.
  22057. CREATE PROCEDURE sp_MSupdatelastsyncinfo
  22058.     @publisher      sysname,                    -- publishing server name
  22059.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22060.     @publication    sysname,                    -- publication name,
  22061.     @subscription_type int,
  22062.     @last_sync_status     int,
  22063.     @last_sync_summary     sysname
  22064. AS
  22065.     set nocount on
  22066.     declare @retcode int
  22067.  
  22068.     --  Security Check
  22069.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  22070.     IF @@ERROR <> 0 or @retcode <> 0
  22071.         RETURN(1)
  22072.     
  22073.     if object_id('dbo.MSsubscription_agents') is null
  22074.         return(1)
  22075.  
  22076.     -- For non independent agent publications
  22077.     if @publication is null or @publication = ''
  22078.         set @publication = 'ALL'
  22079.  
  22080.     if not exists (select * from MSsubscription_agents where
  22081.             UPPER(publisher) = UPPER(@publisher)
  22082.             and publisher_db =  @publisher_db
  22083.             and publication = @publication
  22084.             and subscription_type = @subscription_type)
  22085.     begin
  22086.         exec dbo.sp_MSinit_subscription_agent
  22087.             @publisher,
  22088.             @publisher_db,
  22089.             @publication,
  22090.             @subscription_type
  22091.     end
  22092.  
  22093.     update MSsubscription_agents set     
  22094.         last_sync_time = getdate(), 
  22095.         last_sync_status = @last_sync_status, 
  22096.         last_sync_summary = @last_sync_summary
  22097.         where UPPER(publisher) = UPPER(@publisher)
  22098.             and publisher_db =  @publisher_db
  22099.             and publication = @publication
  22100.             and subscription_type = @subscription_type
  22101.  
  22102.     update MSreplication_subscriptions set
  22103.         time = convert(smalldatetime, getdate()) 
  22104.     WHERE UPPER(publisher) = UPPER(@publisher) AND
  22105.         publisher_db  = @publisher_db AND
  22106.         ((@publication = N'ALL' and independent_agent = 0) or 
  22107.         @publication = publication) and
  22108.         subscription_type = @subscription_type
  22109. go
  22110.  
  22111. exec dbo.sp_MS_marksystemobject sp_MSupdatelastsyncinfo
  22112. go
  22113. grant execute on dbo.sp_MSupdatelastsyncinfo to public
  22114. go
  22115.  
  22116.  
  22117. raiserror('Creating procedure sp_MSget_attach_state', 0,1)
  22118. GO
  22119.  
  22120. -- This proc is called by distribution agent.
  22121. CREATE PROCEDURE sp_MSget_attach_state
  22122.     @publisher      sysname,                    -- publishing server name
  22123.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22124.     @publication    sysname,                    -- publication name,
  22125.     @subscription_type int
  22126. AS
  22127.     set nocount on
  22128.     declare @retcode int
  22129.  
  22130.     --  Security Check: public
  22131.     
  22132.     -- For non independent agent publications
  22133.     if @publication is null or @publication = ''
  22134.         set @publication = 'ALL'
  22135.  
  22136.     select attach_state, attach_version from MSsubscription_agents
  22137.         where UPPER(publisher) = UPPER(@publisher)
  22138.             and publisher_db =  @publisher_db
  22139.             and publication = @publication
  22140.             and subscription_type = @subscription_type
  22141. go
  22142.  
  22143. exec dbo.sp_MS_marksystemobject sp_MSget_attach_state
  22144. go
  22145. grant execute on dbo.sp_MSget_attach_state to public
  22146. go
  22147.  
  22148.  
  22149. raiserror('Creating procedure sp_MSreset_attach_state', 0,1)
  22150. GO
  22151.  
  22152. -- This proc is called by distribution agent.
  22153. CREATE PROCEDURE sp_MSreset_attach_state (
  22154.     @publisher      sysname,                    -- publishing server name
  22155.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22156.     @publication    sysname,                    -- publication name,
  22157.     @subscription_type int
  22158.     )
  22159. AS
  22160. BEGIN
  22161.     set nocount on
  22162.     declare @retcode int
  22163.  
  22164.     --  Security Check
  22165.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  22166.     IF @@ERROR <> 0 or @retcode <> 0
  22167.     RETURN(1)
  22168.     
  22169.  
  22170.     -- For non independent agent publications
  22171.     if @publication is null or @publication = ''
  22172.         select @publication = 'ALL'
  22173.  
  22174.     --
  22175.     -- For Queued updating subscriptions, (re)initialize
  22176.     -- the queue
  22177.     --
  22178.     if exists (select * from dbo.MSsubscription_agents 
  22179.         where UPPER(publisher) = UPPER(@publisher)
  22180.             and publisher_db =  @publisher_db
  22181.             and publication = @publication
  22182.             and subscription_type = @subscription_type
  22183.             and update_mode in (2,3,4,5))
  22184.     begin
  22185.         declare @artid int
  22186.  
  22187.         --
  22188.         -- for each article in this subscription
  22189.         --
  22190.         declare #hc_article CURSOR LOCAL FORWARD_ONLY for 
  22191.             select artid 
  22192.             from dbo.MSsubscription_articles as art join dbo.MSsubscription_agents as agent
  22193.                 on art.agent_id = agent.id
  22194.             where UPPER(agent.publisher) = UPPER(@publisher)
  22195.                 and agent.publisher_db =  @publisher_db
  22196.                 and agent.publication = @publication
  22197.                 and agent.subscription_type = @subscription_type
  22198.  
  22199.         open #hc_article
  22200.         fetch #hc_article into @artid
  22201.         while (@@fetch_status = 0)
  22202.         begin        
  22203.             --
  22204.             -- we cannot have an NULL article id
  22205.             --
  22206.             if (@artid IS NULL)
  22207.             begin
  22208.                 raiserror('sp_MSreset_attach_state(debug) - queued article id cannot be NULL', 16, 1)
  22209.                 return (1)
  22210.             end
  22211.  
  22212.             --
  22213.             -- reset the queue
  22214.             --
  22215.             exec @retcode = dbo.sp_MSreset_queue @publisher, @publisher_db, @publication, @artid
  22216.             IF (@retcode != 0 or @@ERROR != 0)
  22217.             begin
  22218.                 raiserror('sp_MSreset_attach_state(debug) - sp_MSreset_queue failed', 16, 2)
  22219.                 return (1)
  22220.             end
  22221.  
  22222.             --
  22223.             -- fetch next article
  22224.             --
  22225.             fetch #hc_article into @artid
  22226.         end
  22227.         close #hc_article
  22228.         deallocate #hc_article
  22229.     end
  22230.  
  22231.     update MSsubscription_agents set attach_state = 0
  22232.         where UPPER(publisher) = UPPER(@publisher)
  22233.             and publisher_db =  @publisher_db
  22234.             and publication = @publication
  22235.             and subscription_type = @subscription_type
  22236. END
  22237. go
  22238.  
  22239. exec dbo.sp_MS_marksystemobject sp_MSreset_attach_state
  22240. go
  22241. grant execute on dbo.sp_MSreset_attach_state to public
  22242. go
  22243.  
  22244. raiserror('Creating procedure sp_MSset_subscription_properties', 0,1)
  22245. GO
  22246.  
  22247. -- This proc is called by distribution agent.
  22248. CREATE PROCEDURE sp_MSset_subscription_properties (
  22249.     @publisher      sysname,                    -- publishing server name
  22250.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22251.     @publication    sysname,                    -- publication name,
  22252.     @subscription_type int,
  22253.     @allow_subscription_copy bit,
  22254.     @queue_id sysname,
  22255.     @update_mode int,
  22256.     @attach_version binary(16),
  22257.     @queue_server sysname = NULL
  22258. )
  22259. AS
  22260. BEGIN
  22261.     set nocount on
  22262.     declare @retcode int
  22263.  
  22264.     --  Security Check
  22265.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  22266.     IF @@ERROR <> 0 or @retcode <> 0
  22267.         RETURN(1)
  22268.     
  22269.     -- For non independent agent publications
  22270.     if @publication is null or @publication = ''
  22271.         set @publication = 'ALL'
  22272.  
  22273.     if @queue_server = N''
  22274.         select @queue_server = NULL
  22275.         
  22276.     if @queue_id = N''
  22277.         select @queue_id = NULL
  22278.  
  22279.     update MSsubscription_agents set      
  22280.         allow_subscription_copy = @allow_subscription_copy,
  22281.         update_mode = @update_mode,
  22282.         queue_id = @queue_id,
  22283.         queue_server = @queue_server,
  22284.         attach_version = @attach_version
  22285.         where UPPER(publisher) = UPPER(@publisher)
  22286.             and publisher_db =  @publisher_db
  22287.             and publication = @publication
  22288.             and subscription_type = @subscription_type
  22289.  
  22290.     --
  22291.     -- for queued pull subscriptions 
  22292.     -- update column update_mode in MSreplication_subscriptions
  22293.     -- as we never know the right update_mode until initialization
  22294.     --
  22295.     if ((@subscription_type = 1) and (@queue_id IS NOT NULL) and
  22296.         exists (select * from MSreplication_subscriptions 
  22297.             WHERE UPPER(publisher) = UPPER(@publisher) AND
  22298.                 publisher_db  = @publisher_db AND
  22299.                 publication = @publication AND
  22300.                 subscription_type = @subscription_type))
  22301.     begin
  22302.         update MSreplication_subscriptions 
  22303.         set update_mode = @update_mode
  22304.         WHERE UPPER(publisher) = UPPER(@publisher) AND
  22305.             publisher_db  = @publisher_db AND
  22306.             publication = @publication AND
  22307.             subscription_type = @subscription_type
  22308.     end
  22309. END
  22310. go
  22311.  
  22312. exec dbo.sp_MS_marksystemobject sp_MSset_subscription_properties
  22313. go
  22314. grant execute on dbo.sp_MSset_subscription_properties to public
  22315. go
  22316.  
  22317. raiserror('Creating procedure sp_MSset_sub_guid', 0,1)
  22318. GO
  22319.  
  22320. -- This proc is called by distribution agent.
  22321. CREATE PROCEDURE sp_MSset_sub_guid (
  22322.     @publisher      sysname,                    -- publishing server name
  22323.     @publisher_db   sysname,                    -- publishing database name. If NULL then same as current db
  22324.     @publication    sysname,                    -- publication name,
  22325.     @subscription_type int,
  22326.     @subscription_guid binary(16),
  22327.     @queue_id        sysname,
  22328.     @queue_server    sysname = NULL
  22329. )
  22330. AS
  22331. BEGIN
  22332.     set nocount on
  22333.     declare @retcode int
  22334.     declare @independent_agent bit
  22335.  
  22336.     --  Security Check
  22337.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  22338.     IF @@ERROR <> 0 or @retcode <> 0
  22339.     RETURN(1)
  22340.  
  22341.     -- For non independent agent publications
  22342.     if @publication is null or @publication = ''
  22343.     begin
  22344.         set @publication = 'ALL'
  22345.         set @independent_agent = 0
  22346.     end
  22347.     else
  22348.         set @independent_agent = 1
  22349.  
  22350.     if @queue_id = N''
  22351.         select @queue_id = NULL
  22352.  
  22353.     if @queue_server = N''
  22354.         select @queue_server = NULL
  22355.  
  22356.     update MSsubscription_agents set      
  22357.         queue_id = @queue_id
  22358.         ,queue_server = @queue_server
  22359.         where UPPER(publisher) = UPPER(@publisher)
  22360.             and publisher_db =  @publisher_db
  22361.             and publication = @publication
  22362.             and subscription_type = @subscription_type
  22363.  
  22364.     update MSreplication_subscriptions set      
  22365.         [time] = getdate(),
  22366.         subscription_guid = @subscription_guid
  22367.         where UPPER(publisher) = UPPER(@publisher)
  22368.             and publisher_db =  @publisher_db
  22369.             and (@independent_agent = 0 or publication = @publication)
  22370.             and subscription_type = @subscription_type
  22371.             and independent_agent = @independent_agent
  22372. END
  22373. go
  22374.  
  22375. exec dbo.sp_MS_marksystemobject sp_MSset_sub_guid
  22376. go
  22377. grant execute on dbo.sp_MSset_sub_guid to public
  22378. go
  22379.  
  22380.  
  22381. raiserror('Creating procedure sp_MScreate_sub_tables', 0,1)
  22382. GO
  22383.  
  22384. CREATE PROCEDURE sp_MScreate_sub_tables (
  22385. @tran_sub_table bit = 0,
  22386. @property_table bit = 1,
  22387. @sqlqueue_table bit = 0
  22388. )
  22389. as
  22390. BEGIN
  22391.     set nocount on
  22392.     declare @retcode int
  22393.  
  22394.     IF @tran_sub_table = 1 and
  22395.         (NOT EXISTS (SELECT * FROM sysobjects WHERE 
  22396.         type = 'U' AND name = 'MSreplication_subscriptions')) 
  22397.     BEGIN
  22398.         CREATE TABLE dbo.MSreplication_subscriptions
  22399.         (
  22400.         publisher sysname NOT NULL,
  22401.         publisher_db sysname NOT NULL, 
  22402.         publication sysname NULL, 
  22403.         independent_agent bit NOT NULL,
  22404.         subscription_type int NOT NULL,
  22405.         distribution_agent sysname NULL, 
  22406.         time smalldatetime NOT NULL,
  22407.         description nvarchar(255) NULL,
  22408.         transaction_timestamp varbinary(16) NOT NULL,
  22409.         -- SyncTran
  22410.         update_mode tinyint NOT NULL,
  22411.         agent_id binary(16) NULL,
  22412.         subscription_guid binary(16) NULL,
  22413.         subid binary(16) NULL,
  22414.         immediate_sync bit NOT NULL default 1 -- sync_mode with a default of 1
  22415.         )
  22416.         IF @@ERROR <> 0
  22417.             GOTO UNDO
  22418.         CREATE UNIQUE CLUSTERED INDEX uc1MSReplication_subscriptions ON
  22419.                 MSreplication_subscriptions(publication, publisher_db, publisher, subscription_type)
  22420.         IF @@ERROR <> 0
  22421.             GOTO UNDO
  22422.  
  22423.         EXEC dbo.sp_MS_marksystemobject 'MSreplication_subscriptions'
  22424.          IF @@ERROR <> 0
  22425.             GOTO UNDO
  22426.     END    
  22427.  
  22428.  
  22429.     IF @tran_sub_table = 1
  22430.     BEGIN
  22431.         IF NOT EXISTS (SELECT * FROM sysobjects WHERE 
  22432.             type = 'U' AND name = 'MSsubscription_agents') 
  22433.         BEGIN
  22434.             CREATE TABLE dbo.MSsubscription_agents
  22435.             (
  22436.             id int identity,
  22437.             publisher sysname NOT NULL,
  22438.             publisher_db sysname NOT NULL, 
  22439.             publication sysname NOT NULL, 
  22440.             subscription_type int NOT NULL,
  22441.             queue_id sysname NULL,
  22442.             update_mode tinyint default 0 not null, -- 0 = read only, 1 = sync/immediate, 2 = queued, 3 = failover, 4 = sqlqueued, 5 = sqlqueued failover
  22443.             failover_mode bit default 0 not null, -- 0 - sync/immediate, 1 = queued
  22444.             spid int NOT NULL,
  22445.             login_time datetime NOT NULL,
  22446.             allow_subscription_copy bit default 0 not null,
  22447.             attach_state int default 0 not null,    -- 0: not attached 1 attached but not processed 2 attached and processed.
  22448.             attach_version binary(16) default newid() not null,
  22449.             last_sync_status int NULL, -- allow null for upgrade
  22450.             last_sync_summary sysname NULL, -- allow null for upgrade
  22451.             last_sync_time datetime NULL, -- allow null for upgrade
  22452.             queue_server sysname NULL -- only used for MSMQ based updating subscribers
  22453.             )
  22454.             IF @@ERROR <> 0
  22455.                 GOTO UNDO
  22456.  
  22457.             CREATE unique CLUSTERED INDEX ucMSsubscription_agents ON dbo.MSsubscription_agents
  22458.                 (publication, publisher_db, publisher, subscription_type)
  22459.  
  22460.             CREATE INDEX ucMSsubscription_agents_id ON dbo.MSsubscription_agents
  22461.                 (id)
  22462.  
  22463.             EXEC dbo.sp_MS_marksystemobject 'MSsubscription_agents'
  22464.             IF @@ERROR <> 0
  22465.                 GOTO UNDO
  22466.  
  22467.             grant select on dbo.MSsubscription_agents to public
  22468.             IF @@ERROR <> 0
  22469.                 GOTO UNDO
  22470.         END
  22471.         ELSE
  22472.         BEGIN
  22473.             --
  22474.             -- table exists - add new columns
  22475.             --
  22476.             if not exists (select * from dbo.syscolumns where 
  22477.                 id = object_id('MSsubscription_agents') and
  22478.                 name = 'queue_server')
  22479.             begin
  22480.                 alter table dbo.MSsubscription_agents add queue_server sysname NULL
  22481.                 exec dbo.sp_MSupdate_mqserver_subdb
  22482.             end
  22483.         END
  22484.      END
  22485.  
  22486.     IF @property_table = 1 and
  22487.         NOT EXISTS (SELECT * FROM sysobjects WHERE 
  22488.         type = 'U' AND
  22489.         name = 'MSsubscription_properties')
  22490.     BEGIN
  22491.         BEGIN TRAN
  22492.  
  22493.         CREATE TABLE dbo.MSsubscription_properties
  22494.         (
  22495.         publisher                        sysname        NOT NULL,
  22496.         publisher_db                    sysname        NOT NULL,
  22497.         publication                        sysname        NOT NULL,
  22498.         publication_type                int            NOT NULL,
  22499.         publisher_login                    sysname        NULL,
  22500.         publisher_password                nvarchar(524) NULL,
  22501.         publisher_security_mode            int            NOT NULL,
  22502.         distributor                        sysname        NULL,
  22503.         distributor_login                sysname        NULL,
  22504.         distributor_password            nvarchar(524) NULL,
  22505.         distributor_security_mode        int            NOT NULL,
  22506.         ftp_address                        sysname        NULL,
  22507.         ftp_port                        int            NULL,
  22508.         ftp_login                        sysname        NULL,
  22509.         ftp_password                    nvarchar(524) NULL,
  22510.         alt_snapshot_folder             nvarchar(255) NULL,
  22511.         working_directory               nvarchar(255) NULL,
  22512.         use_ftp                            bit default 0 NOT NULL,
  22513.         dts_package_name                sysname NULL,
  22514.         dts_package_password            nvarchar(524) NULL,
  22515.         -- default to be at the subscriber
  22516.         dts_package_location            int    default 1 NOT NULL,
  22517.         enabled_for_syncmgr                bit default 0 NOT NULL,
  22518.         offload_agent                   bit default 0 NOT NULL,
  22519.         offload_server                  sysname     NULL,
  22520.         dynamic_snapshot_location       nvarchar(255) NULL
  22521.         )
  22522.         IF @@ERROR <> 0
  22523.             GOTO UNDO
  22524.  
  22525.         CREATE UNIQUE CLUSTERED INDEX uc1MSsubscription_properties ON
  22526.                 MSsubscription_properties(publication, publisher_db, publisher)
  22527.         IF @@ERROR <> 0
  22528.             GOTO UNDO
  22529.         
  22530.         EXEC @retcode = dbo.sp_MS_marksystemobject 'MSsubscription_properties'
  22531.         if @retcode <> 0 or @@error <> 0
  22532.             GOTO UNDO
  22533.  
  22534.         COMMIT TRAN
  22535.     END
  22536.  
  22537.     IF @sqlqueue_table = 1
  22538.     BEGIN
  22539.         declare @folddata bit
  22540.  
  22541.         BEGIN TRAN    
  22542.         if EXISTS (SELECT * FROM dbo.sysobjects WHERE 
  22543.                 type = 'U' AND name = 'MSreplication_queue')
  22544.         BEGIN
  22545.             --
  22546.             -- table exists - check if we need to add columns
  22547.             --
  22548.             if not exists (select * from dbo.syscolumns where 
  22549.                     id = object_id('MSreplication_queue') and
  22550.                     name = 'cmdstate')
  22551.             BEGIN
  22552.                 ALTER TABLE dbo.MSreplication_queue ADD cmdstate bit DEFAULT 0 NOT NULL
  22553.                 IF @@ERROR <> 0
  22554.                     GOTO UNDO
  22555.             END    
  22556.  
  22557.             --
  22558.             -- change data column from text to varbinary(8000)
  22559.             -- SPECIAL CASE : since a simple ALTER does not work here
  22560.             -- we create a temp table to save the existing data and then
  22561.             -- recreate the table
  22562.             --
  22563.             if exists (select * from dbo.syscolumns 
  22564.                 where id = object_id('MSreplication_queue') and
  22565.                 name = 'data' and xtype = 34)
  22566.             begin
  22567.                 --
  22568.                 -- save existing column data
  22569.                 --
  22570.                 if exists (select * from dbo.MSreplication_queue)
  22571.                 begin
  22572.                     select @folddata = 1
  22573.                     create table #olddata (
  22574.                         publisher                    sysname collate database_default not null ,
  22575.                         publisher_db                sysname collate database_default not null ,
  22576.                         publication                    sysname collate database_default not null ,
  22577.                         tranid                        sysname collate database_default not null ,
  22578.                         data                        varbinary(8000) NULL ,
  22579.                         datalen                     int,
  22580.                         commandtype                    int,
  22581.                         insertdate                    datetime ,
  22582.                         orderkey                    bigint,
  22583.                         cmdstate                    bit)
  22584.                         
  22585.                     insert into #olddata 
  22586.                         select publisher, publisher_db, publication, tranid, CAST(data as varbinary(8000)), 
  22587.                                 datalen, commandtype, insertdate, orderkey, cmdstate 
  22588.                         from dbo.MSreplication_queue
  22589.                     if @@error != 0
  22590.                         goto UNDO
  22591.                 end
  22592.  
  22593.                 --
  22594.                 -- drop table
  22595.                 --
  22596.                 DROP TABLE dbo.MSreplication_queue
  22597.                 IF @@ERROR <> 0
  22598.                     GOTO UNDO                
  22599.             end        
  22600.         END
  22601.  
  22602.         --
  22603.         -- Create table if it does not exist
  22604.         --
  22605.         if NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE 
  22606.                 type = 'U' AND name = 'MSreplication_queue')        
  22607.         BEGIN        
  22608.             CREATE TABLE dbo.MSreplication_queue (
  22609.                 publisher                     sysname NOT NULL ,
  22610.                 publisher_db                 sysname NOT NULL ,
  22611.                 publication                 sysname NOT NULL ,
  22612.                 tranid                         sysname NOT NULL ,
  22613.                 data                         varbinary(8000) NULL ,
  22614.                 datalen                     int DEFAULT 0 ,
  22615.                 commandtype                 int NULL ,
  22616.                 insertdate                     datetime DEFAULT GETDATE(),
  22617.                 orderkey                    bigint IDENTITY(1,1) PRIMARY KEY,
  22618.                 cmdstate                    bit DEFAULT 0 NOT NULL
  22619.             )
  22620.             IF @@ERROR <> 0
  22621.                 GOTO UNDO
  22622.  
  22623.             /****
  22624.             CREATE NONCLUSTERED INDEX nc1MSreplication_queue ON
  22625.                     MSreplication_queue(tranid)
  22626.             IF @@ERROR <> 0
  22627.                 GOTO UNDO
  22628.             ****/
  22629.  
  22630.             EXEC @retcode = dbo.sp_MS_marksystemobject 'MSreplication_queue'
  22631.             if @retcode <> 0 or @@error <> 0
  22632.                 GOTO UNDO
  22633.  
  22634.             --
  22635.             -- Do we need to restore old data
  22636.             --
  22637.             if (@folddata = 1)
  22638.             begin
  22639.                 insert dbo.MSreplication_queue (publisher, publisher_db, publication, tranid, data,
  22640.                             datalen, commandtype, insertdate, cmdstate)
  22641.                     select publisher, publisher_db, publication, tranid, data, 
  22642.                                 datalen, commandtype, insertdate, cmdstate 
  22643.                         from #olddata
  22644.                         order by orderkey
  22645.                 if @@error != 0
  22646.                     goto UNDO
  22647.                 
  22648.                 drop table #olddata
  22649.                 if @@error != 0
  22650.                     goto UNDO
  22651.             end
  22652.         END
  22653.         COMMIT TRAN
  22654.     END
  22655.  
  22656.     return(0)
  22657.     
  22658. UNDO:
  22659.     IF @@TRANCOUNT = 1
  22660.         ROLLBACK TRAN
  22661.     ELSE
  22662.         COMMIT TRAN  
  22663.     return(1) 
  22664. END
  22665. go
  22666.  
  22667. exec dbo.sp_MS_marksystemobject sp_MScreate_sub_tables
  22668. go
  22669.  
  22670. --
  22671. -- sp_MSupdate_mqserver_subdb
  22672. --
  22673. -- This procedure is called to upgrade the MSMQ related entries in 
  22674. -- MSsubscription_agents in subscription database - this processing 
  22675. -- cannot be done directly inside sp_MScreate_sub_tables since we need the 
  22676. -- queue_server column for the processing and we can get a syntax error 
  22677. -- if the table exists without the column
  22678. --
  22679. -- Assumption : MSsubscription_agents has been created 
  22680. --                and column queue_server exists
  22681. --
  22682. raiserror('Creating procedure sp_MSupdate_mqserver_subdb', 0,1)
  22683. GO
  22684. create procedure sp_MSupdate_mqserver_subdb
  22685. as
  22686. begin
  22687.     if exists (select * from dbo.MSsubscription_agents
  22688.         where queue_id IS NOT NULL and queue_id != N'mssqlqueue' and queue_server IS NULL)
  22689.     begin
  22690.         --
  22691.         -- we have entries for active Queued subscriptions using MSMQ that need upgrade
  22692.         --
  22693.         declare @queue_server sysname
  22694.                 ,@publisher sysname
  22695.                 ,@publisher_db sysname
  22696.                 ,@publication sysname
  22697.  
  22698.         DECLARE hC CURSOR LOCAL FAST_FORWARD FOR 
  22699.             select publisher, publisher_db, publication
  22700.             from dbo.MSsubscription_agents
  22701.             where queue_id IS NOT NULL 
  22702.                 and queue_id != N'mssqlqueue' 
  22703.                 and queue_server IS NULL
  22704.  
  22705.         OPEN hC
  22706.         FETCH hC INTO @publisher, @publisher_db, @publication
  22707.         WHILE (@@fetch_status != -1)
  22708.         BEGIN
  22709.             --
  22710.             -- the table MSsubscription_properties has to exist;
  22711.             -- prepare the queue server name from distributor name
  22712.             -- strip the instance name if necessary
  22713.             --
  22714.             select @queue_server = ISNULL(distributor, @@servername)
  22715.             from dbo.MSsubscription_properties
  22716.             where UPPER(publisher) = UPPER(@publisher) and
  22717.                         publisher_db = @publisher_db and
  22718.                         publication = @publication
  22719.  
  22720.             if (charindex(N'\', @queue_server) > 0)
  22721.                 select @queue_server = substring(@queue_server, 1, charindex(N'\', @queue_server) - 1)
  22722.  
  22723.             --
  22724.             -- set the queue_server for this entry
  22725.             --
  22726.             update dbo.MSsubscription_agents
  22727.             set queue_server = @queue_server
  22728.             where UPPER(publisher) = UPPER(@publisher) and
  22729.                         publisher_db = @publisher_db and
  22730.                         publication = @publication
  22731.  
  22732.             --
  22733.             -- get next entry
  22734.             --
  22735.             FETCH hC INTO @publisher, @publisher_db, @publication
  22736.         END
  22737.         CLOSE hC
  22738.         DEALLOCATE hC
  22739.     end
  22740. end
  22741. go
  22742. exec dbo.sp_MS_marksystemobject sp_MSupdate_mqserver_subdb
  22743. go
  22744.  
  22745. raiserror('Creating procedure sp_MS_replication_installed', 0,1)
  22746. GO
  22747.  
  22748. CREATE PROCEDURE sp_MS_replication_installed
  22749. as
  22750.     set nocount on
  22751.  
  22752.     declare @isinstalled int
  22753.     select @isinstalled = 0
  22754.     
  22755.     create table #keyvalues (keyvalue nvarchar(255) collate database_default not null, keyvaluedata nvarchar(255) collate database_default null)
  22756.  
  22757.     declare @instance sysname
  22758.     declare @regkey nvarchar(260)
  22759.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  22760.     select @regkey = 'SOFTWARE\Microsoft\'
  22761.     -- default installation
  22762.     if @instance is null
  22763.         SELECT @regkey = @regkey + 'MSSQLServer\Replication' 
  22764.     else
  22765.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Replication'
  22766.  
  22767.     insert into #keyvalues exec master..xp_regenumvalues 'HKEY_LOCAL_MACHINE',
  22768.         @regkey
  22769.     
  22770.     if @@ERROR <> 0
  22771.     begin
  22772.         drop table #keyvalues
  22773.         return (-1)
  22774.     end
  22775.  
  22776.     select @isinstalled = convert (int, (select keyvaluedata from #keyvalues where keyvalue = N'IsInstalled'))
  22777.     
  22778.     drop table #keyvalues
  22779.  
  22780.     if (@isinstalled is null or @isinstalled = 0)
  22781.     begin
  22782.         raiserror (21028, 16, -1)
  22783.         return (0)
  22784.     end
  22785.  
  22786.     return (1)
  22787. go
  22788. exec dbo.sp_MS_marksystemobject sp_MS_replication_installed
  22789. go
  22790.  
  22791. raiserror('Creating procedure sp_MSunc_to_drive', 0,1)
  22792. GO
  22793.  
  22794. CREATE PROCEDURE sp_MSunc_to_drive (
  22795.         @unc_path nvarchar(255), 
  22796.         @local_server sysname, 
  22797.         @local_path nvarchar(255) output
  22798.         )
  22799.     AS
  22800.  
  22801.     SET NOCOUNT ON
  22802.  
  22803.     declare @pattern nvarchar(150)
  22804.  
  22805.     select @pattern = N'\\' + upper(@local_server) + N'\'
  22806.  
  22807.     if    charindex(@pattern, upper(substring(@unc_path, 1, len(@pattern)))) <> 0 
  22808.         and charindex(N'$\', substring(@unc_path, len(@pattern)+2, 2))<>0
  22809.         select @local_path = substring(@unc_path, len(@pattern) + 1, 1) + N':' +
  22810.             substring(@unc_path, len(@pattern) + 3, len(@unc_path) - len(@pattern) -1)
  22811.     else
  22812.         select @local_path = @unc_path
  22813. GO
  22814. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  22815. go
  22816.  
  22817. raiserror('Creating procedure sp_MSretrieve_publication_attributes', 0,1)
  22818. GO
  22819. create proc sp_MSretrieve_publication_attributes 
  22820. @name             sysname,
  22821. @database         sysname
  22822. AS
  22823.  
  22824. SET NOCOUNT ON
  22825.  
  22826. declare @mergepublish_bit    int
  22827. declare @tranpublish_bit    int
  22828. declare @procname            nvarchar(640)
  22829. declare @retcode            int
  22830.  
  22831. select @mergepublish_bit    = 4 
  22832. select @tranpublish_bit     = 1
  22833.  
  22834. /*
  22835. ** Security Check, will be checked inside sp_MSretrieve_publication
  22836. ** and sp_MSretrieve_mergepublication
  22837. */
  22838.  
  22839. create table #publication_property (
  22840.     Name                     sysname collate database_default,
  22841.     dbanme                    sysname collate database_default,
  22842.     Publisher                sysname collate database_default,
  22843.     Type                    nvarchar(15) collate database_default,
  22844.     Description                nvarchar(255) collate database_default,
  22845.     Status                    tinyint,
  22846.     allow_pull                bit,
  22847.     allow_sync_tran            bit,
  22848.     allow_anonymous            bit,
  22849.     allow_queued_tran        bit,
  22850.     enabled_for_internet    bit,
  22851.     third_party                bit
  22852. )
  22853.  
  22854. if (select category & @tranpublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  22855.     begin
  22856.         select @procname = quotename(@database) + '.dbo.sp_MSretrieve_publication '
  22857.         insert into #publication_property exec @retcode = @procname @name
  22858.     end
  22859.  
  22860. if (select category & @mergepublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  22861.     begin
  22862.         select @procname = quotename(@database) + '.dbo.sp_MSretrieve_mergepublication '
  22863.         insert into #publication_property exec @retcode = @procname @name
  22864.     end
  22865. select * from #publication_property
  22866. drop table #publication_property
  22867. Go
  22868. exec dbo.sp_MS_marksystemobject sp_MSretrieve_publication_attributes
  22869. go
  22870.  
  22871. raiserror('Creating procedure sp_MScleanup_publication_ADinfo', 0,1)
  22872. GO
  22873. create proc sp_MScleanup_publication_ADinfo 
  22874. @name             sysname,
  22875. @database         sysname
  22876. AS
  22877.  
  22878. SET NOCOUNT ON
  22879.  
  22880. declare @mergepublish_bit    int
  22881. declare @tranpublish_bit    int
  22882. declare @cmd            nvarchar(640)
  22883.  
  22884. select @mergepublish_bit    = 4 
  22885. select @tranpublish_bit     = 1
  22886.  
  22887. /*
  22888. ** Security Check
  22889. */
  22890. select @cmd = quotename(@database) + '.dbo.sp_MSreplcheck_publish'
  22891. exec (@cmd)
  22892. IF @@ERROR <> 0
  22893.     return (1)
  22894.  
  22895. if (select category & @tranpublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  22896.     begin
  22897.         select @cmd = N'update' + quotename(@database) + N'.dbo.syspublications set ad_guidname=NULL where name=N' + quotename(@name, N'''')
  22898.         exec (@cmd)
  22899.     end
  22900.  
  22901. if (select category & @mergepublish_bit from master..sysdatabases where name = @database collate database_default) <> 0
  22902.     begin
  22903.         select @cmd = N'update' + quotename(@database) + N'.dbo.sysmergepublications set ad_guidname=NULL where name=N' + quotename(@name, N'''')
  22904.         exec (@cmd)
  22905.     end
  22906. Go
  22907. exec dbo.sp_MS_marksystemobject sp_MScleanup_publication_ADinfo
  22908. go
  22909.  
  22910. raiserror('Creating procedure sp_MSrepl_linkedservers_rowset', 0,1)
  22911. GO
  22912. create proc sp_MSrepl_linkedservers_rowset @srvname sysname
  22913. as
  22914.     select
  22915.         SVR_NAME         = srvname,
  22916.         SVR_PRODUCT        = srvproduct,
  22917.         SVR_PROVIDERNAME    = providername,
  22918.         SVR_DATASOURCE        = datasource,
  22919.         SVR_PROVIDERSTRING    = providerstring,
  22920.         SVR_LOCATION        = location,
  22921.         SVR_CATALOG        = catalog
  22922.     from master.dbo.sysservers
  22923.     where UPPER(srvname) = UPPER(@srvname) collate database_default and 
  22924.     isnull(providername,' ') <> ' ' and
  22925.     ( isnull(datasource, ' ') <> ' ' or
  22926.     isnull(location, ' ') <> ' ' or
  22927.     isnull(providerstring, ' ') <> ' '  or
  22928.     isnull(catalog, ' ') <> ' ' )
  22929.     order by 1    
  22930.  
  22931.     if @@error <> 0
  22932.         return 1
  22933.     else
  22934.         return 0
  22935. go
  22936. exec dbo.sp_MS_marksystemobject sp_MSrepl_linkedservers_rowset
  22937. go
  22938.  
  22939.  
  22940.  
  22941. raiserror('Creating procedure sp_MSregistersubscription', 0,1)
  22942. go
  22943.  
  22944. CREATE PROCEDURE sp_MSregistersubscription (
  22945.     @replication_type            int, /* Transactional = 1, Merge = 2 */
  22946.     @publisher                     sysname,
  22947.     @publisher_db                 sysname,
  22948.     @publisher_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  22949.     @publisher_login            sysname = NULL,
  22950.     @publisher_password    nvarchar(524) = NULL,
  22951.     @publication                 sysname,         
  22952.     @subscriber                 sysname,
  22953.     @subscriber_db                 sysname,
  22954.     @subscriber_security_mode    int = NULL,                        /* 0 standard; 1 integrated */
  22955.     @subscriber_login            sysname = NULL,
  22956.     @subscriber_password        nvarchar(524) = NULL,
  22957.     @distributor                 sysname,
  22958.     @distributor_security_mode     int = NULL,
  22959.     @distributor_login             sysname = NULL,
  22960.     @distributor_password        nvarchar(524) = NULL,
  22961.     @subscription_id            uniqueidentifier ,
  22962.     @independent_agent            int = NULL,
  22963.     @subscription_type            int,
  22964.     @use_interactive_resolver    int = NULL,
  22965.     @failover_mode                int = NULL
  22966.     ) AS
  22967.  
  22968.     SET NOCOUNT ON
  22969.  
  22970.     /* MobileSync Support */
  22971.     declare @subscription_name                nvarchar(1000)
  22972.     declare @regkey                            nvarchar(1000)
  22973.     declare @subidstr                        nvarchar(38)
  22974.     declare @profile_name                     nvarchar(100)
  22975.     declare @retcode                        int
  22976.     declare @publisher_encrypted_password    nvarchar(524)
  22977.     declare @subscriber_encrypted_password    nvarchar(524)
  22978.     declare @distributor_encrypted_password    nvarchar(524)
  22979.     declare @temp_binary_password            varbinary(1048)
  22980.  
  22981.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  22982.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  22983.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  22984.     set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  22985.     set @subidstr = '{' + convert ( nchar(36), @subscription_id) + '}'
  22986.     set @profile_name = formatmessage(20550) -- SyncMgr Profile
  22987.  
  22988.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  22989.                                @regkey,
  22990.                                'ProfileName',
  22991.                                'REG_SZ',
  22992.                                 @profile_name    
  22993.     if @retcode <> 0 OR @@ERROR <> 0
  22994.         return 1
  22995.  
  22996.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  22997.                                @regkey,
  22998.                                'ReplicationType',
  22999.                                'REG_DWORD',
  23000.                                 @replication_type    
  23001.     if @retcode <> 0 OR @@ERROR <> 0
  23002.         return 1
  23003.  
  23004.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23005.                                @regkey,
  23006.                                'SubscriptionType',
  23007.                                'REG_DWORD',
  23008.                                 @subscription_type    
  23009.     if @retcode <> 0 OR @@ERROR <> 0
  23010.         return 1
  23011.  
  23012.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23013.                                @regkey,
  23014.                                'Subid',
  23015.                                'REG_SZ',
  23016.                                 @subidstr    
  23017.     if @retcode <> 0 OR @@ERROR <> 0
  23018.         return 1
  23019.  
  23020.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23021.                                @regkey,
  23022.                                'Publisher',
  23023.                                'REG_SZ',
  23024.                                 @publisher                                        
  23025.     if @retcode <> 0 OR @@ERROR <> 0
  23026.         return 1
  23027.  
  23028.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23029.                                @regkey,
  23030.                                'PublisherDb',
  23031.                                'REG_SZ',
  23032.                                 @publisher_db
  23033.     if @retcode <> 0 OR @@ERROR <> 0
  23034.         return 1
  23035.  
  23036.     
  23037.     IF @use_interactive_resolver IS NOT NULL
  23038.     BEGIN
  23039.         EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23040.                                @regkey,
  23041.                                'UseInteractiveResolver',
  23042.                                'REG_DWORD',
  23043.                                 @use_interactive_resolver
  23044.         if @retcode <> 0 OR @@ERROR <> 0
  23045.             return 1
  23046.     END
  23047.  
  23048.     /* If Publisher security mode is NOT NULL, write out the entries */
  23049.     if @publisher_security_mode IS NOT NULL
  23050.         begin
  23051.                EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23052.                                        @regkey,
  23053.                                        'PublisherSecurityMode',
  23054.                                        'REG_DWORD',
  23055.                                         @publisher_security_mode
  23056.             if @retcode <> 0 OR @@ERROR <> 0
  23057.                 return 1
  23058.  
  23059.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23060.                                        @regkey,
  23061.                                        'PublisherLogin',
  23062.                                        'REG_SZ',
  23063.                                         @publisher_login                                    
  23064.             if @retcode <> 0 OR @@ERROR <> 0
  23065.                 return 1
  23066.  
  23067.             /* Encrypt the password before writing to the registry */
  23068.             set @publisher_encrypted_password = @publisher_password
  23069.             exec @retcode = master.dbo.xp_repl_encrypt @publisher_encrypted_password OUTPUT
  23070.             if @retcode <> 0 OR @@ERROR <> 0
  23071.                 return 1
  23072.  
  23073.             select @temp_binary_password = convert(varbinary(1048), @publisher_encrypted_password)
  23074.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23075.                                        @regkey,
  23076.                                        'PublisherEncryptedPasswordBinary',
  23077.                                        'REG_BINARY',
  23078.                                         @temp_binary_password
  23079.             if @retcode <> 0 OR @@ERROR <> 0
  23080.                 return 1
  23081.  
  23082.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23083.                                        @regkey,
  23084.                                        'PublisherEncryptedPassword',
  23085.                                        'REG_SZ',
  23086.                                         @publisher_encrypted_password
  23087.             if @retcode <> 0 OR @@ERROR <> 0
  23088.                 return 1
  23089.         end
  23090.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23091.                                @regkey,
  23092.                                'Publication',
  23093.                                'REG_SZ',
  23094.                                 @publication
  23095.     if @retcode <> 0 OR @@ERROR <> 0
  23096.         return 1
  23097.  
  23098.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23099.                                @regkey,
  23100.                                'Subscriber',
  23101.                                'REG_SZ',
  23102.                                 @subscriber
  23103.     if @retcode <> 0 OR @@ERROR <> 0
  23104.         return 1
  23105.  
  23106.     /* If Subscriber security mode is NOT NULL, write out the entries */
  23107.     if @subscriber_security_mode IS NOT NULL
  23108.         begin
  23109.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23110.                                @regkey,
  23111.                                'SubscriberSecurityMode',
  23112.                                'REG_DWORD',
  23113.                                 @subscriber_security_mode
  23114.             if @retcode <> 0 OR @@ERROR <> 0
  23115.                 return 1
  23116.  
  23117.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23118.                                @regkey,
  23119.                                'SubscriberLogin',
  23120.                                'REG_SZ',
  23121.                                 @subscriber_login                                    
  23122.             if @retcode <> 0 OR @@ERROR <> 0
  23123.                 return 1
  23124.  
  23125.             /* Encrypt the password before writing to the registry */
  23126.             set @subscriber_encrypted_password = @subscriber_password
  23127.             exec @retcode = master.dbo.xp_repl_encrypt @subscriber_encrypted_password OUTPUT
  23128.             if @retcode <> 0 OR @@ERROR <> 0
  23129.                 return 1
  23130.  
  23131.             select @temp_binary_password = convert(varbinary(1048), @subscriber_encrypted_password)
  23132.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23133.                                @regkey,
  23134.                                'SubscriberEncryptedPasswordBinary',
  23135.                                'REG_BINARY',
  23136.                                 @temp_binary_password
  23137.             if @retcode <> 0 OR @@ERROR <> 0
  23138.                 return 1
  23139.  
  23140.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23141.                                @regkey,
  23142.                                'SubscriberEncryptedPassword',
  23143.                                'REG_SZ',
  23144.                                 @subscriber_encrypted_password
  23145.             if @retcode <> 0 OR @@ERROR <> 0
  23146.                 return 1
  23147.         end
  23148.  
  23149.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23150.                                @regkey,
  23151.                                'SubscriberDb',
  23152.                                'REG_SZ',
  23153.                                 @subscriber_db                                    
  23154.     if @retcode <> 0 OR @@ERROR <> 0
  23155.         return 1
  23156.                 
  23157.     EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23158.                                @regkey,
  23159.                                'Distributor',
  23160.                                'REG_SZ',
  23161.                                 @distributor
  23162.     if @retcode <> 0 OR @@ERROR <> 0
  23163.         return 1
  23164.  
  23165.     /* If Distributor security mode is NOT NULL, write out the entries */
  23166.     if @distributor_security_mode IS NOT NULL
  23167.         begin
  23168.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23169.                                @regkey,
  23170.                                'DistributorSecurityMode',
  23171.                                'REG_DWORD',
  23172.                                 @distributor_security_mode
  23173.             if @retcode <> 0 OR @@ERROR <> 0
  23174.                 return 1
  23175.  
  23176.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23177.                                @regkey,
  23178.                                'DistributorLogin',
  23179.                                'REG_SZ',
  23180.                                 @distributor_login                                    
  23181.             if @retcode <> 0 OR @@ERROR <> 0
  23182.                 return 1
  23183.  
  23184.             /* Encrypt the password before writing to the registry */
  23185.             set @distributor_encrypted_password = @distributor_password
  23186.             exec @retcode = master.dbo.xp_repl_encrypt @distributor_encrypted_password OUTPUT
  23187.             if @retcode <> 0 OR @@ERROR <> 0
  23188.                 return 1
  23189.  
  23190.             select @temp_binary_password = convert(varbinary(1048), @distributor_encrypted_password)
  23191.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23192.                                @regkey,
  23193.                                'DistributorEncryptedPasswordBinary',
  23194.                                'REG_BINARY',
  23195.                                 @temp_binary_password
  23196.             if @retcode <> 0 OR @@ERROR <> 0
  23197.                 return 1
  23198.  
  23199.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23200.                                @regkey,
  23201.                                'DistributorEncryptedPassword',
  23202.                                'REG_SZ',
  23203.                                 @distributor_encrypted_password
  23204.             if @retcode <> 0 OR @@ERROR <> 0
  23205.                 return 1
  23206.         end
  23207.     if @independent_agent IS NOT NULL
  23208.         begin
  23209.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23210.                                @regkey,
  23211.                                'IndependentAgent',
  23212.                                'REG_DWORD',
  23213.                                 @independent_agent    
  23214.             if @retcode <> 0 OR @@ERROR <> 0
  23215.                 return 1
  23216.         end                
  23217.  
  23218.     IF @failover_mode IS NOT NULL
  23219.         begin
  23220.             EXECUTE @retcode = master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE',
  23221.                                @regkey,
  23222.                                'FailoverMode',
  23223.                                'REG_DWORD',
  23224.                                 @failover_mode    
  23225.             if @retcode <> 0 OR @@ERROR <> 0
  23226.                 return 1
  23227.  
  23228.         end            
  23229.  
  23230.     -- Mark enabled_for_syncmgr bit if every thing succeeded.
  23231.     -- If the row exists in MSreplication_properties table, 
  23232.     -- set enabled_for_syncmgr bit
  23233.     -- The logic need to be here because UI call this sp directly.
  23234.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  23235.     begin
  23236.         update MSsubscription_properties set enabled_for_syncmgr = 1 where
  23237.             UPPER(publisher) = UPPER(@publisher)
  23238.             and publisher_db =  @publisher_db
  23239.             and publication = @publication
  23240.         if @retcode <> 0 OR @@ERROR <> 0
  23241.             return 1
  23242.     end
  23243.  
  23244.     return 0
  23245. GO
  23246.  
  23247. raiserror('Creating procedure sp_MSunregistersubscription', 0,1)
  23248. go
  23249.  
  23250. CREATE PROCEDURE sp_MSunregistersubscription
  23251.         @publisher         sysname = NULL, 
  23252.         @publisher_db     sysname = NULL, 
  23253.         @publication     sysname = NULL, 
  23254.         @subscriber     sysname = NULL,
  23255.         @subscriber_db     sysname = NULL
  23256.     AS
  23257.  
  23258.     /* 
  23259.     ** Drop the corresponding registry entry for MobileSync
  23260.     */
  23261.     declare @enabled            int
  23262.     declare    @retcode             int
  23263.     declare @regkey                nvarchar(1000)
  23264.     
  23265.     select @retcode = 0
  23266.     -- Mark enabled_for_syncmgr bit before trying to delete the key
  23267.     -- If the row exists in MSreplication_properties table, 
  23268.     -- set enabled_for_syncmgr bit
  23269.     -- The logic need to be here because UI call this sp directly.
  23270.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  23271.     begin
  23272.         update MSsubscription_properties set enabled_for_syncmgr = 0 where
  23273.             UPPER(publisher) = UPPER(@publisher)
  23274.             and publisher_db =  @publisher_db
  23275.             and publication = @publication
  23276.         if @@ERROR <> 0
  23277.             return 1
  23278.     end
  23279.  
  23280.     -- regdelete returns 'Access Denied' message if key does not exist; check before delete
  23281.     exec sp_MSsubscription_enabled_for_syncmgr
  23282.         @publisher, @publisher_db, @publication, @subscriber, @subscriber_db, @enabled OUT, @regkey OUT
  23283.     if @@ERROR <> 0
  23284.         return 1
  23285.         
  23286.     if @enabled = 1
  23287.         begin
  23288.             EXECUTE @retcode = master.dbo.xp_regdeletekey 'HKEY_LOCAL_MACHINE', @regkey
  23289.             if @@error <> 0 OR @retcode <> 0
  23290.                 return 1
  23291.         end
  23292.  
  23293.     return 0        
  23294.  
  23295. GO
  23296.  
  23297. raiserror('Creating procedure sp_MSsubscription_enabled_for_syncmgr', 0,1)
  23298. go
  23299.  
  23300. CREATE PROCEDURE sp_MSsubscription_enabled_for_syncmgr
  23301.         @publisher         sysname = NULL, 
  23302.         @publisher_db     sysname = NULL, 
  23303.         @publication     sysname = NULL, 
  23304.         @subscriber     sysname = NULL,
  23305.         @subscriber_db     sysname = NULL,
  23306.         @enabled        int = NULL OUTPUT,
  23307.         @regkey            nvarchar(1000) = NULL OUTPUT
  23308.     AS
  23309.  
  23310.     /* 
  23311.     ** Drop the corresponding registry entry for MobileSync
  23312.     */
  23313.     declare @subscription_name     nvarchar(1000)
  23314.     declare @keyexist            int
  23315.     
  23316.     -- no reg key to clean up for virtual subscribers
  23317.     if @subscriber is null
  23318.     begin
  23319.         select @enabled = 0
  23320.         return 0
  23321.     end
  23322.     
  23323.     set @subscription_name = @publisher + ':' + @publisher_db + ':' + @publication + ':' + @subscriber + ':' + @subscriber_db
  23324.     /* Replace back slash with forward slash so that the key name is a valid REGISTRY key name */
  23325.     set @subscription_name = REPLACE(@subscription_name,'\','/')
  23326.     set @regkey = 'SOFTWARE\Microsoft\Microsoft SQL Server\80\Replication\Subscriptions\' + @subscription_name
  23327.     create table #keyexist (keyexist int)
  23328.     insert into #keyexist EXECUTE master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', @regkey
  23329.     select @enabled = keyexist from #keyexist
  23330.     drop table #keyexist
  23331.     return 0        
  23332.  
  23333. GO
  23334.  
  23335.  
  23336. raiserror('Creating procedure sp_MSget_jobstate', 0,1)
  23337. go
  23338.  
  23339. -- Procedure sp_MSget_jobstate
  23340. --    The proc takes a specific Job ID and returns the Job State of the job
  23341. --        Returns a row with one column job_state
  23342. --        Returns a row with NULL if job does not exist
  23343. -- 
  23344.  
  23345. CREATE PROCEDURE sp_MSget_jobstate
  23346.     @job_id             UNIQUEIDENTIFIER
  23347. AS
  23348. BEGIN
  23349.     DECLARE @is_sysadmin INT
  23350.     DECLARE @job_owner   sysname
  23351.     DECLARE @job_state   INT 
  23352.     DECLARE @job_id_as_char VARCHAR(36)
  23353.  
  23354.     SET NOCOUNT ON
  23355.  
  23356.     CREATE TABLE #xp_results (job_id                UNIQUEIDENTIFIER NOT NULL,
  23357.                             last_run_date         INT              NOT NULL,
  23358.                             last_run_time         INT              NOT NULL,
  23359.                             next_run_date         INT              NOT NULL,
  23360.                             next_run_time         INT              NOT NULL,
  23361.                             next_run_schedule_id  INT              NOT NULL,
  23362.                             requested_to_run      INT              NOT NULL, -- BOOL
  23363.                             request_source        INT              NOT NULL,
  23364.                             request_source_id     sysname          collate database_default null,
  23365.                             running               INT              NOT NULL, -- BOOL
  23366.                             current_step          INT              NOT NULL,
  23367.                             current_retry_attempt INT              NOT NULL,
  23368.                             job_state             INT              NOT NULL)
  23369.  
  23370.     -- Need a job_id
  23371.     if (@job_id IS NULL)
  23372.     BEGIN
  23373.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  23374.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  23375.         RETURN(1) -- Failure
  23376.     END
  23377.  
  23378.     -- Capture job execution information (for local jobs only since that's all SQLServerAgent caches)
  23379.     SELECT @is_sysadmin = ISNULL(IS_SRVROLEMEMBER(N'sysadmin'), 0)
  23380.     SELECT @job_owner = suser_sname(suser_sid())
  23381.     INSERT INTO #xp_results
  23382.     EXECUTE master.dbo.xp_sqlagent_enum_jobs @is_sysadmin, @job_owner
  23383.  
  23384.     -- Select the job state of the job in question
  23385.     SELECT @job_state = job_state FROM #xp_results WHERE @job_id = job_id
  23386.  
  23387.     -- Error if we have no rows selected
  23388.     if (@job_state IS NULL)
  23389.     BEGIN
  23390.         SELECT @job_id_as_char = CONVERT(VARCHAR(36), @job_id)
  23391.         RAISERROR(14262, -1, -1, '@job_id', @job_id_as_char)
  23392.         RETURN(1) -- Failure
  23393.     END
  23394.     ELSE
  23395.         SELECT @job_state
  23396.     
  23397.     -- All done
  23398.     DROP TABLE #xp_results
  23399.     RETURN(0)    -- Success
  23400. END
  23401. GO
  23402.  
  23403. raiserror('Creating procedure sp_MSscript_pkvar_assignment', 0,1)
  23404. go
  23405. create procedure sp_MSscript_pkvar_assignment
  23406. (
  23407.     @objid          int,
  23408.     @columns      binary(32), 
  23409.     @indent       int = 0,
  23410.     @identity_col sysname = NULL, -- Not null value used by trigger scripting
  23411.     @ts_col       sysname = NULL,  -- Not null value used by trigger scripting
  23412.     @primary_key_bitmap varbinary(4000) = null
  23413. )
  23414. as
  23415. begin
  23416.     -- This stored procedure will assign the '_old' var to new var
  23417.     -- based on @bitmap. This is to avoid using case statement
  23418.     -- in the where clause in the synctran pub proc, which
  23419.     -- will cause a table scan.
  23420.     declare @cmd          nvarchar(4000)
  23421.         ,@spacer       nvarchar(20)
  23422.         ,@indkey       int
  23423.         ,@indid        int
  23424.         ,@this_col     int
  23425.         ,@col          sysname
  23426.         ,@qualname     nvarchar(512)
  23427.         ,@column          nvarchar(255)
  23428.         ,@key          sysname
  23429.         ,@src_cols      int
  23430.         ,@total_col        int
  23431.         ,@fcreatedcolmap    bit
  23432.         ,@art_col int -- relative position of column
  23433.     declare @colmap table (relativeorder int identity(1,1), colid int)
  23434.  
  23435.     select @spacer = N'select '
  23436.         ,@cmd = N''
  23437.         ,@indkey = 1
  23438.         ,@indid = 0
  23439.         ,@fcreatedcolmap = 0
  23440.     exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  23441.     select @src_cols = max(colid)
  23442.             ,@total_col = count(colid)
  23443.         from syscolumns where id = @objid
  23444.     exec dbo.sp_MSpad_command @cmd output, @indent
  23445.     exec dbo.sp_MSflush_command @cmd output, 1, @indent
  23446.  
  23447.     if @primary_key_bitmap is null
  23448.     begin
  23449.         exec @indid = dbo.sp_MStable_has_unique_index @objid
  23450.         if @indid is null
  23451.         begin
  23452.             raiserror('Debug: Cannot find unique index', 16, -1)
  23453.             return (1)
  23454.         end
  23455.     end
  23456.  
  23457.     --
  23458.     -- check if column Id match relative column order
  23459.     -- for trigger scripting
  23460.     --
  23461.     if ((@total_col < @src_cols) and 
  23462.         (@columns is null) and (@primary_key_bitmap is not null))
  23463.     begin
  23464.         --
  23465.         -- this table may have altered columns, so when we need to 
  23466.         -- set a mapping for using the bitmaps properly as the bitmap
  23467.         -- always refers relative column order
  23468.         --
  23469.         insert into @colmap (colid)
  23470.             select colid from syscolumns where id = @objid order by colid
  23471.         if (@@error != 0)
  23472.         begin
  23473.             raiserror('Could not create column mapping', 16, -1)
  23474.             return (1)
  23475.         end
  23476.         select @fcreatedcolmap = 1
  23477.     end
  23478.  
  23479.     while (1=1)
  23480.     begin
  23481.         if @primary_key_bitmap is null 
  23482.         begin
  23483.             select @key = index_col(@qualname, @indid, @indkey)
  23484.             if @key is null
  23485.                 break
  23486.             exec dbo.sp_MSget_col_position @objid, @columns, @key, @col output, @this_col output
  23487.         end
  23488.         else
  23489.         begin
  23490.             exec dbo.sp_MSget_map_position @primary_key_bitmap, @indkey, @col output, @this_col output
  23491.             if @this_col is null
  23492.                 break
  23493.  
  23494.                 --
  23495.                 -- set the actual column id for this relative order in the PK bitmap if necessary
  23496.                 --
  23497.             if (@fcreatedcolmap = 1)
  23498.             begin
  23499.                 select @art_col = @this_col
  23500.                 select @this_col = colid
  23501.                     ,@col = 'c' + convert(sysname, colid) 
  23502.                 from @colmap 
  23503.                 where relativeorder = @art_col 
  23504.             end
  23505.             else
  23506.             begin
  23507.                 select @art_col = NULL
  23508.             end
  23509.  
  23510.             -- Get column name
  23511.             exec dbo.sp_MSget_colinfo @objid, @this_col, @columns, 0, @key output
  23512.         end
  23513.  
  23514.         select @indkey = @indkey + 1
  23515.  
  23516.         if @key in (@identity_col, @ts_col)
  23517.             continue
  23518.  
  23519.         select @cmd = @spacer + N'@c' + convert(nvarchar(10), @this_col)
  23520.  
  23521.         -- Get the new values for the columns in primary key.
  23522.         exec dbo.sp_MSget_synctran_column 
  23523.             @ts_col = null,
  23524.             @op_type = null , -- 'ins, 'upd', 'del'
  23525.             @is_new = null,
  23526.             @primary_key_bitmap = null,
  23527.             @colname = null,
  23528.             @this_col = @this_col,
  23529.             @column = @column output,
  23530.             @from_proc = 0,
  23531.             @coltype = null,
  23532.             @type = 'pk_var',
  23533.             @art_col = @art_col
  23534.             select @cmd = @cmd + N' = ' + @column 
  23535.             select @spacer = ',
  23536.     '
  23537.  
  23538.         -- flush command if necessary
  23539.         exec dbo.sp_MSflush_command @cmd output, 1, @indent
  23540.     end
  23541.  
  23542. end
  23543. go
  23544.  
  23545. raiserror('Creating procedure sp_MSget_publication_from_taskname', 0,1)
  23546. go
  23547. create procedure sp_MSget_publication_from_taskname
  23548.     @taskname     sysname,
  23549.     @publisher    sysname, 
  23550.     @publisherdb  sysname,
  23551.     @publication  sysname OUTPUT
  23552. as
  23553.     declare @value       sysname
  23554.     declare @value2      sysname
  23555.     declare @position    INT
  23556.  
  23557.     select @publication = NULL
  23558.  
  23559.     -- Parse out publication name from the task name "publisher_publisherdb_publication_number"
  23560.     -- Expect publisher name
  23561.     if charindex(@publisher, @taskname) <> 1
  23562.     begin
  23563.         return 1
  23564.     end   
  23565.  
  23566.     -- Eat up the publisher name
  23567.     select @value = stuff(@taskname, 1, len(@publisher), N'')  
  23568.  
  23569.     -- Expect '_' + publisherdb + '_'
  23570.     select @value2 = N'_' + @publisherdb + N'_'
  23571.     if charindex(@value2, @value) <> 1
  23572.     begin
  23573.         return 1
  23574.     end
  23575.  
  23576.     -- Eat up '_' + publisherdb + '_'
  23577.     select  @value = stuff(@value, 1, LEN(@publisherdb) + 2, N'')
  23578.       
  23579.     -- Reverse the string in the hope of finding the first '_' 
  23580.     -- from the right which denotes the end of the publication 
  23581.     -- name. The number at the end should not contain '_'
  23582.     select @value2 = reverse(@value)
  23583.     select @position = charindex(N'_', @value2)
  23584.     if @position < 2
  23585.     begin
  23586.         return 1
  23587.     end
  23588.        
  23589.     select @publication = left(@value, len(@value) - @position)      
  23590.     return 0
  23591. go
  23592.  
  23593. EXEC dbo.sp_MS_marksystemobject sp_MSget_publication_from_taskname
  23594. go
  23595.  
  23596. -- sp_MSacquireHeadofQueueLock, sp_MSacquireSlotLock and sp_MSreleaseSlotLock work together
  23597. -- to ensure the number of concurrent merge processes does not exceed a given value. A merge
  23598. -- process has to acquire headofqueue, i.e., Im-First lock before it can acquire slot lock. 
  23599. -- All merge processes are queued for the Im-First lock and only the one process holding that
  23600. -- lock will poll to see if there is any slot available for it to get it.
  23601.  
  23602. raiserror('Creating procedure sp_MSacquireHeadofQueueLock', 0,1)
  23603. GO
  23604.  
  23605. CREATE PROC sp_MSacquireHeadofQueueLock 
  23606. @process_name                    sysname,
  23607. @queue_timeout                    int = 0,  -- means wait inâ•–definitely
  23608. @no_result                      bit = 0,
  23609. @return_immediately                bit = 0      -- if 1, do not wait: return and post a progress message.
  23610. AS
  23611. declare @entry_date        datetime
  23612. declare @delay_time        int --in second
  23613. declare @retcode         int
  23614. declare @max_waiting    int
  23615. declare @lock_acquired    bit
  23616.  
  23617. -- Security Checking 
  23618. -- sysadmin or db_owner or replication agent have access
  23619. if is_srvrolemember('sysadmin') <> 1 and 
  23620.         is_member('db_owner') <> 1 and
  23621.         sessionproperty('replication_agent') <> 1
  23622.     begin
  23623.         raiserror(14260, 16, -1)
  23624.         return (1)
  23625.     end
  23626.  
  23627. if @queue_timeout<0
  23628.     begin
  23629.         raiserror(21344, 16, -1, '@queue_timeout')
  23630.         return (1)        
  23631.     end
  23632.         
  23633. if @queue_timeout> 3600*12 -- more than 12 hours is not allowed: make it 0 in this case.
  23634.     begin
  23635.         raiserror(21417, 16, -1) 
  23636.         return (1)
  23637.     end
  23638.  
  23639. --quick peek and leave
  23640. if @return_immediately=1
  23641.     begin
  23642.         --take a peek: return without wait regardless of whether the lock is successfully acquired.
  23643.         exec @retcode=sp_getapplock @Resource=@process_name,@LockMode=N'Exclusive',@LockOwner='Session',@LockTimeout=0
  23644.         if (@retcode <> 0 AND @retcode <> -1)
  23645.             begin
  23646.                 RAISERROR(21414,16,-1)
  23647.                 RETURN(@retcode)
  23648.             end
  23649.         IF (@retcode = 0)       -- AppLock acquired
  23650.             select 1, 0         -- 1 means lock acquired, 0 is the time consumed to acquired this lock.
  23651.         else if @retcode = -1    -- AppLock is not available    
  23652.             select 0, 0            -- first 0 means lock not available, second column will be ignored.
  23653.         return (0)                -- OK
  23654.     end        
  23655.  
  23656. -- from now on, @return_immediately=0
  23657. --if @queue_timeout=0, means waiting indefinitely
  23658. if @queue_timeout=0
  23659.     select @max_waiting = NULL
  23660. else
  23661. --otherwise convert to minisecond and pass it down.
  23662.     select @max_waiting = @queue_timeout * 1000
  23663.  
  23664.  
  23665. select @delay_time=0
  23666. select @entry_date=getdate()
  23667.  
  23668. -- First try to acquire EXCLUSIVE lock which signfies at front of queue.   i.e. I'm next.
  23669.  
  23670. exec @retcode=sp_getapplock @process_name, @LockMode=N'Exclusive',@LockOwner=N'Session', @LockTimeout=@max_waiting
  23671. -- We shouldn't return from above until we have it 
  23672. -- RC should be either 0 (got immediately) or 1 (waited and got it eventually) or -1 (timed out); Exit on anything else.
  23673. -- We need value -1 because @LockTimeout value is no longer NULL, meaning waiting indefinitely. It is possible 
  23674. -- that we waited for a given length of time and timed out
  23675. IF (@retcode <> 0 and @retcode <> 1) and @retcode<>-1
  23676.     BEGIN
  23677.         RAISERROR(21413, 16, -1)
  23678.         RETURN(@retcode)
  23679.     END
  23680.     
  23681. -- Im-first lock is to be released after successfully obtained a slot lock later.
  23682. select @delay_time=datediff(ss, @entry_date, getdate())
  23683. if @retcode=-1
  23684.     select @lock_acquired=0
  23685. else
  23686.     select @lock_acquired=1
  23687.  
  23688. if @no_result = 0
  23689. begin
  23690.     select @lock_acquired, @delay_time
  23691. end
  23692.  
  23693. RETURN(0)
  23694.  
  23695. exec dbo.sp_MS_marksystemobject sp_MSacquireHeadofQueueLock
  23696. go
  23697.  
  23698. grant execute on dbo.sp_MSacquireHeadofQueueLock to public
  23699. go
  23700.  
  23701. -- this stored procedure is called by merge agent to limit the max number of
  23702. -- concurrent merge processes at publisher side. The merge process that calls
  23703. -- this SP must be the one that is currently holding HeadOfQueue lock. Once
  23704. -- a slot lock is granted, HeadOfQueue lock will be released for use the next
  23705. -- merge process waiting in the queue for that lock.
  23706. -- @queue_timeout value gives
  23707. -- the maximum length of time (in seconds) a merge agent would like to wait
  23708. -- before acquring Im-first lock and the available serve slots. A value of 0
  23709. -- means it would wait indefinitely until getting the lock or being canceled
  23710. -- by the caller of the procedure
  23711.  
  23712. raiserror('Creating procedure sp_MSacquireSlotLock', 0,1)
  23713. GO
  23714.  
  23715. CREATE PROC sp_MSacquireSlotLock 
  23716. @process_name                    sysname,
  23717. @concurrent_max                 int,
  23718. @queue_timeout                    int = 0,-- means wait inâ•–definitely
  23719. @return_immediately                bit = 0 -- if set to 1, take a peek at the server and return immediately.
  23720.  
  23721. AS
  23722. declare @entry_date        datetime
  23723. declare @slot_name         nvarchar(150)  -- OUTPUT - must give back slot acquired to caller so caller can later release.
  23724. declare @basetime         datetime
  23725. declare @delaytime         datetime
  23726. declare @retcode         int
  23727. declare @i                int
  23728. declare @lock_acquired  bit
  23729.  
  23730. -- Security Checking 
  23731. -- sysadmin or db_owner or replication agent have access
  23732. if is_srvrolemember('sysadmin') <> 1 and 
  23733.         is_member('db_owner') <> 1 and
  23734.         sessionproperty('replication_agent') <> 1
  23735.     begin
  23736.         raiserror(14260, 16, -1)
  23737.         return (1)
  23738.     end
  23739.  
  23740. select @lock_acquired = 0
  23741. if @queue_timeout<0
  23742.     begin
  23743.         raiserror(21344, 16, -1, '@queue_timeout')
  23744.         return (1)        
  23745.     end
  23746.     
  23747. if @concurrent_max<=0
  23748.     begin
  23749.         raiserror(21344, 16, -1, '@concurrent_max')
  23750.         return (1)        
  23751.     end
  23752.         
  23753. select @entry_date=getdate()
  23754. select @delaytime = '00:00:02' --polling interval is defaulted to 2 seconds
  23755.  
  23756. SET @slot_name=NULL -- If terminate anywhere unexpectedly, dont want to give caller a lock they didnt really get.
  23757.  
  23758. -- We are at front of queue, so check if any available 'slot' is open.   
  23759. -- We do not wait at all for these locks, and hence expect either it was granted or timed out (-1).
  23760.  
  23761. SET @i=1
  23762.  
  23763. WHILE (@i <= @concurrent_max)
  23764.     BEGIN
  23765.         --the process has waited long enough. quit now and try later. If @queue_timeout is 0, keep waiting until succeeds.
  23766.         if @queue_timeout>0 and DATEADD(second, -@queue_timeout,  getdate()) > @entry_date
  23767.             begin
  23768.                 select @lock_acquired = 1 -- not a peek but has waited as specified
  23769.                 select @slot_name = NULL -- waited but failed to get one
  23770.                 BREAK
  23771.             end
  23772.  
  23773.         SET @slot_name=@process_name+convert(varchar,@i)
  23774.         
  23775.         --the call is not blocking, return immediately having acquired the lock or not
  23776.         exec @retcode=sp_getapplock @Resource=@slot_name,@LockMode=N'Exclusive',@LockOwner='Session',@LockTimeout=0
  23777.         IF (@retcode <> 0 AND @retcode <> -1)
  23778.             BEGIN
  23779.                 RAISERROR(21414,16,-1)
  23780.                 RETURN(@retcode)
  23781.             END
  23782.     
  23783.         IF (@retcode = 0)       -- got lock for that slot - cleanup and leave.
  23784.             BEGIN
  23785.                 -- Release the "Im first lock"
  23786.                 exec @retcode=sp_releaseapplock @process_name,@LockOwner=N'Session'
  23787.                 IF (@retcode <> 0)
  23788.                 BEGIN
  23789.                     SET @slot_name=NULL
  23790.                     RAISERROR(21415, 16, -1)
  23791.                     RETURN(@retcode)
  23792.                 END
  23793.                 select @lock_acquired = 1
  23794.             -- We got our slot and released the Im first lock.  We're done.
  23795.                 BREAK
  23796.             END
  23797.         ELSE
  23798.         IF (@retcode = -1)  -- Couldn't immediately get the lock.  So try the next one.
  23799.             BEGIN
  23800.             SET @i=@i+1
  23801.                 IF @i <= @concurrent_max
  23802.                     CONTINUE   -- restart the loop
  23803.                 ELSE
  23804.                     BEGIN        -- Sleep and start over.
  23805.                     if @return_immediately=1
  23806.                         begin
  23807.                             select @lock_acquired = 0 --slot name does not matter in this case
  23808.                             BREAK
  23809.                         end
  23810.                     else
  23811.                         begin
  23812.                             WAITFOR DELAY @delaytime
  23813.                             SET @i=1
  23814.                             CONTINUE   -- restart the loop
  23815.                         end
  23816.                     END
  23817.             END
  23818.         
  23819.     END
  23820.     
  23821.     --output the slot name for the purpose of releasing the lock by the caller
  23822.     --if the value if NULL, the caller does not acquire the lock
  23823.     select @lock_acquired, @slot_name
  23824. RETURN(0)
  23825.  
  23826. exec dbo.sp_MS_marksystemobject sp_MSacquireSlotLock
  23827. go
  23828.  
  23829. grant execute on dbo.sp_MSacquireSlotLock to public
  23830. go
  23831.  
  23832. -- this procedure is called by merge process to release slot lock
  23833. -- that is acquired by calling sp_MSacquireSlotLock.
  23834.  
  23835. raiserror('Creating procedure sp_MSreleaseSlotLock', 0,1)
  23836. GO
  23837.  
  23838. -- this stored procedure is called by merge agent to release the application lock
  23839. -- acquired by sp_MSacquireSlotLock
  23840.  
  23841. CREATE PROC sp_MSreleaseSlotLock
  23842. @process_name    sysname
  23843. AS
  23844. declare @retcode int
  23845.  
  23846. -- Security Checking 
  23847. -- sysadmin or db_owner or replication agent have access
  23848.  
  23849. if is_srvrolemember('sysadmin') <> 1 and 
  23850.         is_member('db_owner') <> 1 and
  23851.         sessionproperty('replication_agent') <> 1
  23852.     begin
  23853.         raiserror(14260, 16, -1)
  23854.         return (1)
  23855.     end
  23856.  
  23857. exec @retcode=sp_releaseapplock @process_name,@LockOwner=N'Session'
  23858. IF (@retcode <> 0)
  23859.     BEGIN
  23860.         RAISERROR(21415, 16, -1)
  23861.         return (1)
  23862.     END
  23863. return @retcode
  23864. GO
  23865. exec dbo.sp_MS_marksystemobject sp_MSreleaseSlotLock 
  23866. go
  23867. grant exec on dbo.sp_MSreleaseSlotLock to public
  23868. go
  23869.  
  23870. raiserror('Creating procedure sp_MSrepl_check_server', 0,1)
  23871. go
  23872.  
  23873. CREATE PROCEDURE sp_MSrepl_check_server (
  23874.     @srvname sysname,
  23875.     @check_distdb bit = 0
  23876.         ) AS
  23877.     -- This sp is called by sp_dropserver to check if the server is in use by replication.
  23878.     declare @subscriber_bit smallint
  23879.     declare @distributor_bit smallint
  23880.     declare @retcode int
  23881.     declare @proc nvarchar(255)
  23882.     declare @dbname sysname
  23883.  
  23884.     -- Intialize
  23885.     select @distributor_bit = 8
  23886.     select @subscriber_bit = 4
  23887.  
  23888.     if @check_distdb = 0
  23889.     begin
  23890.         -- Check to see if the server is marked as a Distributor
  23891.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  23892.             srvstatus & @distributor_bit <> 0)
  23893.         begin
  23894.             raiserror(20581, 16, -1, @srvname) 
  23895.             return (1)
  23896.         end
  23897.         -- Check to see if the server is marked as a subscriber
  23898.         if exists (select * from sysservers where UPPER(srvname) = UPPER(@srvname) and
  23899.             srvstatus & @subscriber_bit <> 0)
  23900.         begin
  23901.             raiserror(20583, 16, -1, @srvname) 
  23902.             return (1)
  23903.         end
  23904.         -- Check to see if the server is a dist publisher
  23905.         if object_id('msdb.dbo.MSdistpublishers') is not null
  23906.         begin
  23907.             if exists (select * from msdb.dbo.MSdistpublishers where
  23908.                 UPPER(name) = UPPER(@srvname) collate database_default)
  23909.             begin
  23910.                 raiserror(20582, 16, -1, @srvname) 
  23911.                 return (1)
  23912.             end
  23913.         end
  23914.         -- Check to see if the server is in use as a subscriber in the distribution dbs.
  23915.         if object_id('msdb.dbo.MSdistributiondbs') is not null
  23916.         begin
  23917.             declare hCForEachDb CURSOR LOCAL FAST_FORWARD FOR 
  23918.                 select name from msdb.dbo.MSdistributiondbs
  23919.             FOR READ ONLY
  23920.             open hCForEachDb
  23921.             fetch hCForEachDb into @dbname
  23922.             /* Loop for each database */
  23923.             while (@@fetch_status >= 0) 
  23924.             begin
  23925.                 select @proc = quotename(@dbname) + '.dbo.sp_MSrepl_check_server'
  23926.                 exec @retcode = @proc
  23927.                     @srvname = @srvname,
  23928.                     @check_distdb = 1
  23929.                 if @retcode <> 0 or @@error <> 0
  23930.                     return (1)
  23931.                 fetch hCForEachDb into @dbname
  23932.             end /* while FETCH_SUCCESS */
  23933.         end
  23934.     end
  23935.     else
  23936.     begin
  23937.         if object_id('MSsubscriber_info') is not null
  23938.         begin
  23939.             declare @publisher sysname
  23940.             select @publisher =  publisher from MSsubscriber_info sub
  23941.                 where UPPER(subscriber) = UPPER(@srvname)
  23942.             if @publisher is not null
  23943.             begin
  23944.                 raiserror(20584, 16, -1, @srvname, @publisher) 
  23945.                 return (1)
  23946.             end
  23947.         end
  23948.     end
  23949.  
  23950. GO
  23951.  
  23952. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_check_server
  23953. go
  23954.  
  23955. grant execute on dbo.sp_MSrepl_check_server to public
  23956. go
  23957.  
  23958. raiserror('Creating procedure sp_MSreset_synctran_bit', 0,1)
  23959. go
  23960. CREATE PROCEDURE sp_MSreset_synctran_bit (
  23961.     @owner          sysname,
  23962.     @table          sysname
  23963. )AS
  23964.     declare @qualified_name nvarchar(300)
  23965.     declare @synctran_bit int
  23966.  
  23967.     select @synctran_bit            = 256
  23968.     
  23969.     if @owner = N''
  23970.         select @qualified_name = @table
  23971.     else
  23972.         select @qualified_name = quotename(@owner) + '.' + quotename(@table) 
  23973.  
  23974.     -- Unmark synctran bit
  23975.     update sysobjects set replinfo = replinfo & ~@synctran_bit where 
  23976.         id = object_id(@qualified_name) and
  23977.         (replinfo & @synctran_bit) <> 0
  23978.     IF @@ERROR <> 0 
  23979.         return(1)
  23980.     return(0)
  23981. GO
  23982.  
  23983. EXEC dbo.sp_MS_marksystemobject sp_MSreset_synctran_bit
  23984. go
  23985.  
  23986. grant execute on dbo.sp_MSreset_synctran_bit to public
  23987. go
  23988.  
  23989. --
  23990. -- sp_MSenum_replsqlqueues
  23991. --
  23992. -- proc that enumerates all the subscriber + subscriber_db for the currently 
  23993. -- active queued subscriptions in all the distribution databases in this system
  23994. --
  23995. raiserror('Creating procedure sp_MSenum_replsqlqueues', 0,1)
  23996. go
  23997. create procedure sp_MSenum_replsqlqueues
  23998. (
  23999.     @curdistdb    sysname = NULL
  24000. )
  24001. as
  24002. begin
  24003.     declare @distbit int
  24004.     declare @db_name sysname
  24005.     declare @cmd nvarchar(1024)
  24006.  
  24007.     select @distbit = 16
  24008.  
  24009.     --
  24010.     -- create the temp table to store the relevant information
  24011.     --
  24012.     create table #replqueue (
  24013.         publisher sysname collate database_default not null,
  24014.         publisher_db sysname collate database_default not null,
  24015.         subscriber sysname collate database_default not null,
  24016.         subscriber_db sysname collate database_default not null,
  24017.         publication sysname collate database_default not null,
  24018.         dist_db sysname collate database_default not null
  24019.     )
  24020.     create unique index ucreplqueue ON #replqueue (subscriber, subscriber_db, publication)
  24021.  
  24022.     --
  24023.     -- Has the user specified a distribution database
  24024.     --
  24025.     if (@curdistdb is NULL)
  24026.     begin
  24027.         --
  24028.         -- Go through all the distribution databases
  24029.         --
  24030.         declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR 
  24031.             select name from master.dbo.sysdatabases 
  24032.             where
  24033.                 category & @distbit <> 0 and
  24034.                 has_dbaccess(name) = 1
  24035.             for read only
  24036.     end
  24037.     else
  24038.     begin
  24039.         --
  24040.         -- User specified Distribution Database
  24041.         -- Validate the user specified name
  24042.         --
  24043.         if exists (select name from master.dbo.sysdatabases 
  24044.         where
  24045.             name = @curdistdb and
  24046.             category & @distbit <> 0 and
  24047.             has_dbaccess(name) = 1)
  24048.         begin
  24049.             declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
  24050.             select @curdistdb
  24051.             for read only
  24052.         end
  24053.         else
  24054.         begin
  24055.             --
  24056.             -- Error : Invalid distribution db specified
  24057.             --
  24058.             raiserror(20587, 16, 3, N'@curdistdb', N'sp_MSenum_replsqlqueues')
  24059.             return 1
  24060.         end
  24061.     end
  24062.     
  24063.     --
  24064.     -- Enumerate
  24065.     --
  24066.     open hCdatabase
  24067.     fetch next from hCdatabase into @db_name
  24068.     while (@@fetch_status <> -1)
  24069.     begin
  24070.         select @cmd =
  24071.         'SET NOCOUNT ON ' +
  24072.         'INSERT INTO #replqueue (publisher, publisher_db, subscriber, subscriber_db, publication, dist_db) ' +
  24073.         'SELECT c.srvname, a.publisher_db, b.srvname, a.subscriber_db, a.publication, N''' + @db_name + ''' ' +
  24074.         'FROM ' + QUOTENAME(@db_name) + '.dbo.MSdistribution_agents as a ' +
  24075.             'JOIN master.dbo.sysservers as b ' +
  24076.             'ON a.subscriber_id = b.srvid ' +
  24077.             'JOIN master.dbo.sysservers as c ' + 
  24078.             'ON a.publisher_id = c.srvid ' + 
  24079.             'WHERE queue_id = N''mssqlqueue'' '
  24080.             
  24081.         exec (@cmd)
  24082.         fetch next from hCdatabase into @db_name
  24083.     end
  24084.     close hCdatabase
  24085.     deallocate hCdatabase
  24086.  
  24087.     --
  24088.     -- select the contents of the temp table
  24089.     --
  24090.     select * from #replqueue
  24091.  
  24092.     --
  24093.     -- cleanup
  24094.     --
  24095.     drop table #replqueue
  24096. end
  24097. go
  24098.  
  24099. EXEC dbo.sp_MS_marksystemobject sp_MSenum_replsqlqueues
  24100. go
  24101.  
  24102. --
  24103. -- sp_MSenum_replqueues
  24104. --
  24105. -- proc that enumerates all the MSMQ based queues that are currently active 
  24106. -- in the specified distribution database
  24107. --
  24108. -- Parameter :
  24109. -- @curdistdb    sysname : specified distribution database. If NULL, then
  24110. --             enumerate the queues for all the distribution databases
  24111. --
  24112. raiserror('Creating procedure sp_MSenum_replqueues', 0,1)
  24113. go
  24114. create procedure sp_MSenum_replqueues
  24115. (
  24116.     @curdistdb    sysname = NULL
  24117. )
  24118. as
  24119. begin
  24120.     declare @distbit int
  24121.     declare @db_name sysname
  24122.     declare @cmd nvarchar(1024)
  24123.  
  24124.     select @distbit = 16
  24125.  
  24126.     --
  24127.     -- create the temp table to store the relevant information
  24128.     --
  24129.     create table #replqueue (
  24130.         queue_server sysname collate database_default not null,
  24131.         queue_id sysname collate database_default not null,
  24132.         dist_db sysname collate database_default not null
  24133.     )
  24134.     create unique clustered index ucreplqueue ON #replqueue (queue_id)
  24135.  
  24136.     --
  24137.     -- Has the user specified a distribution database
  24138.     --
  24139.     if (@curdistdb is NULL)
  24140.     begin
  24141.         --
  24142.         -- Go through all the distribution databases
  24143.         --
  24144.         declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR 
  24145.             select name from master.dbo.sysdatabases 
  24146.             where
  24147.                 category & @distbit <> 0 and
  24148.                 has_dbaccess(name) = 1
  24149.             for read only
  24150.     end
  24151.     else
  24152.     begin
  24153.         --
  24154.         -- User specified Distribution Database
  24155.         -- Validate the user specified name
  24156.         --
  24157.         if exists (select name from master.dbo.sysdatabases 
  24158.         where
  24159.             name = @curdistdb and
  24160.             category & @distbit <> 0 and
  24161.             has_dbaccess(name) = 1)
  24162.         begin
  24163.             declare hCdatabase CURSOR LOCAL FAST_FORWARD FOR
  24164.             select @curdistdb
  24165.             for read only
  24166.         end
  24167.         else
  24168.         begin
  24169.             --
  24170.             -- Error : Invalid distribution db specified
  24171.             --
  24172.             raiserror(20587, 16, 4, N'@curdistdb', N'sp_MSenum_replqueues')
  24173.             return 1
  24174.         end
  24175.     end
  24176.  
  24177.     --
  24178.     -- Enumerate
  24179.     --
  24180.     open hCdatabase
  24181.     fetch next from hCdatabase into @db_name
  24182.     while (@@fetch_status <> -1)
  24183.     begin
  24184.         select @cmd =
  24185.         'SET NOCOUNT ON ' +
  24186.         'INSERT INTO #replqueue (queue_server, queue_id, dist_db) ' +
  24187.         'SELECT queue_server, queue_id, ' +
  24188.                 'N''' + replace(@db_name, '''', '''''') + ''' ' +
  24189.         'FROM ' +
  24190.                 QUOTENAME(@db_name) + '.dbo.MSdistribution_agents ' +
  24191.         'WHERE ' +
  24192.                 'queue_id IS NOT NULL and queue_id != N''mssqlqueue'''
  24193.             
  24194.         exec (@cmd)
  24195.         fetch next from hCdatabase into @db_name
  24196.     end
  24197.     close hCdatabase
  24198.     deallocate hCdatabase
  24199.  
  24200.     --
  24201.     -- select the contents of the temp table to present
  24202.     -- the formatted queue name
  24203.     --
  24204.     select     N'DIRECT=OS:' + queue_server + N'\PRIVATE$\' + queue_id AS 'queue_format'
  24205.             ,dist_db
  24206.     from #replqueue
  24207.     
  24208.     --
  24209.     -- cleanup
  24210.     --
  24211.     drop table #replqueue
  24212. end
  24213. go
  24214.  
  24215. EXEC dbo.sp_MS_marksystemobject sp_MSenum_replqueues
  24216. go
  24217.  
  24218. raiserror('Creating procedure sp_browsemergesnapshotfolder', 0,1)
  24219. go
  24220. CREATE PROCEDURE sp_browsemergesnapshotfolder (
  24221.     @publication sysname
  24222.     )
  24223. AS
  24224. BEGIN
  24225.     SET NOCOUNT ON
  24226.     DECLARE @dbname sysname
  24227.     DECLARE @alt_directory_type INT
  24228.     DECLARE @directory_type INT
  24229.     SELECT @alt_directory_type = 25
  24230.     SELECT @directory_type = 7
  24231.  
  24232.     IF (EXISTS (SELECT * FROM sysobjects WHERE name = N'sysmergepublications')) AND
  24233.        (EXISTS (SELECT * FROM sysobjects WHERE name = N'sysmergeschemachange'))
  24234.     BEGIN
  24235.         SELECT 'snapshot_folder' = schematext 
  24236.           FROM sysmergeschemachange sc 
  24237.     INNER JOIN sysmergepublications mp
  24238.             ON sc.pubid = mp.pubid
  24239.          WHERE mp.name = @publication
  24240.            AND upper(mp.publisher) = upper(@@servername)
  24241.            AND publisher_db = db_name()  
  24242.            AND (schematype = @directory_type OR schematype = @alt_directory_type)
  24243.       ORDER BY schematype desc
  24244.     END  
  24245.     ELSE
  24246.     BEGIN
  24247.         SELECT @dbname = DB_NAME()
  24248.         RAISERROR(21147, 16, -1, @dbname)
  24249.         RETURN 1
  24250.     END
  24251. END
  24252. GO
  24253. EXEC dbo.sp_MS_marksystemobject sp_browsemergesnapshotfolder
  24254. go
  24255.  
  24256. raiserror('Creating procedure sp_browsesnapshotfolder', 0,1)
  24257. go
  24258. CREATE PROCEDURE sp_browsesnapshotfolder (
  24259.     @publication    sysname,
  24260.     @subscriber     sysname = NULL,
  24261.     @subscriber_db  sysname = NULL
  24262.     )
  24263. AS
  24264. BEGIN
  24265.     SET NOCOUNT ON
  24266.     DECLARE @retcode        INT
  24267.     DECLARE @publisher      sysname
  24268.     DECLARE @publisher_db   sysname
  24269.     DECLARE @distributor    sysname
  24270.     DECLARE @distributiondb sysname
  24271.     DECLARE @distproc       nvarchar(300)
  24272.     DECLARE @article_id     INT
  24273.     
  24274.     SELECT @retcode = 0
  24275.     SELECT @publisher = NULL
  24276.     SELECT @publisher_db = DB_NAME()
  24277.     SELECT @distributor = NULL
  24278.     SELECT @distributiondb = NULL
  24279.     SELECT @article_id = NULL
  24280.     
  24281.     -- Either both of @subscriber and @subscriber_db are NULL or
  24282.     -- both of them have to be non-null
  24283.     IF ((@subscriber IS NULL OR @subscriber = N'') 
  24284.         AND @subscriber_db IS NOT NULL AND @subscriber_db <> N'') OR
  24285.        ((@subscriber_db IS NULL OR @subscriber_db = N'') 
  24286.         AND @subscriber IS NOT NULL AND @subscriber <> N'')
  24287.     BEGIN
  24288.         RAISERROR(21148, 16, -1)
  24289.     END
  24290.     
  24291.     IF EXISTS (SELECT * FROM sysobjects WHERE name = N'syspublications') AND
  24292.        EXISTS (SELECT * FROM sysobjects WHERE name = N'sysextendedarticlesview')
  24293.     BEGIN    
  24294.         SELECT @publisher = @@SERVERNAME
  24295.     
  24296.         -- Get the smallest article id for the publication since 
  24297.         -- method for identifying a publication is not readily available 
  24298.         -- on the distributor
  24299.  
  24300.         SELECT @article_id = MIN(artid) 
  24301.           FROM sysextendedarticlesview sa
  24302.     INNER JOIN syspublications sp
  24303.             ON sa.pubid = sp.pubid
  24304.          WHERE sp.name = @publication
  24305.  
  24306.         IF @article_id IS NULL
  24307.         BEGIN
  24308.             RAISERROR(20026, 16, -1, @publication)
  24309.         END         
  24310.  
  24311.         EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  24312.                                                @distribdb = @distributiondb OUTPUT
  24313.         IF @retcode <> 0
  24314.             RETURN @retcode
  24315.     
  24316.         SELECT @distributor = RTRIM(@distributor)
  24317.     
  24318.         IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  24319.         BEGIN
  24320.             SELECT @distproc = @distributor + '.' + @distributiondb + 
  24321.                                '.dbo.sp_MSbrowsesnapshotfolder'
  24322.         END
  24323.         ELSE
  24324.         BEGIN
  24325.             SELECT @distproc = @distributiondb + '.dbo.sp_MSbrowsesnapshotfolder'
  24326.         END
  24327.         EXECUTE @retcode = @distproc
  24328.                     @publisher = @publisher, 
  24329.                     @publisher_db = @publisher_db,
  24330.                     @article_id = @article_id,
  24331.                     @subscriber = @subscriber,
  24332.                     @subscriber_db = @subscriber_db
  24333.         RETURN @retcode
  24334.     END
  24335.     ELSE
  24336.     BEGIN
  24337.         RAISERROR(21149, 16, -1, @publisher_db)
  24338.         RETURN 1
  24339.     END
  24340. END
  24341. GO
  24342. EXEC dbo.sp_MS_marksystemobject sp_browsesnapshotfolder
  24343. go
  24344.  
  24345. raiserror('Creating procedure sp_MScopysnapshot', 0,1)
  24346. go
  24347. CREATE PROCEDURE sp_MScopysnapshot (
  24348.     @source_folder           nvarchar(255),
  24349.     @destination_folder      nvarchar(255)
  24350.     )
  24351. AS
  24352. BEGIN
  24353.     SET NOCOUNT ON
  24354.     DECLARE @directory_exists bit    
  24355.     DECLARE @ftporuncdir      nvarchar(5)
  24356.     DECLARE @pubdir           nvarchar(255)
  24357.     DECLARE @timestampdir     nvarchar(255)
  24358.     DECLARE @bslashindex      int
  24359.     DECLARE @bslashindex2     int
  24360.     DECLARE @bslashcounter    int
  24361.     DECLARE @command          nvarchar(1000)
  24362.     DECLARE @retcode          int
  24363.     DECLARE @platform_nt      bit
  24364.  
  24365.     IF platform() & 0x1 = 0x1
  24366.         SELECT @platform_nt = 1
  24367.     ELSE
  24368.         SELECT @platform_nt = 0
  24369.  
  24370.     -- If @source_folder is NULL then either the snapshot has not been 
  24371.     -- generated or it has been cleaned up
  24372.     IF @source_folder IS NULL OR @source_folder = N''
  24373.     BEGIN
  24374.         RAISERROR(21289, 16, -1)
  24375.         RETURN (1)
  24376.     END
  24377.  
  24378.     -- Make sure that the @destination folder is not null
  24379.     IF @destination_folder IS NULL OR
  24380.        @destination_folder = N''
  24381.     BEGIN
  24382.         RAISERROR(21287, 16, -1)      
  24383.         RETURN (1)
  24384.     END
  24385.  
  24386.     -- Append backslash to @destination_folder if it is not 
  24387.     -- there already
  24388.     IF SUBSTRING(@destination_folder, LEN(@destination_folder), 1) <> N'\'
  24389.     BEGIN
  24390.         SELECT @destination_folder = @destination_folder + N'\'
  24391.     END
  24392.  
  24393.     -- Check if the destination folder exists 
  24394.     EXEC sp_MSget_file_existence @destination_folder, @directory_exists OUTPUT
  24395.     IF @directory_exists = 0
  24396.     BEGIN
  24397.         RAISERROR(21287, 16, -1)      
  24398.         RETURN (1)
  24399.     END    
  24400.     
  24401.     -- Parse out the last three components in the source folder 
  24402.     -- Note that the source_folder must have a trailing backslash
  24403.     SELECT @bslashindex = 1
  24404.     SELECT @bslashindex2 = 1
  24405.     SELECT @bslashcounter = 0
  24406.     WHILE (@bslashindex <> 0)
  24407.     BEGIN
  24408.         SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex + 1)
  24409.         SELECT @bslashcounter = @bslashcounter + 1
  24410.         IF @bslashcounter > 4
  24411.         BEGIN
  24412.             SELECT @bslashindex2 = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  24413.         END    
  24414.     END  
  24415.  
  24416.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  24417.     SELECT @ftporuncdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1)
  24418.     SELECT @bslashindex2 = @bslashindex
  24419.  
  24420.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  24421.     SELECT @pubdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1) 
  24422.     SELECT @bslashindex2 = @bslashindex
  24423.  
  24424.     SELECT @bslashindex = CHARINDEX(N'\', @source_folder, @bslashindex2 + 1)
  24425.     SELECT @timestampdir = SUBSTRING(@source_folder, @bslashindex2 + 1, @bslashindex - @bslashindex2 - 1) 
  24426.     SELECT @bslashindex2 = @bslashindex
  24427.         
  24428.     -- Create the subdirectory structure underneath the specified snapshot
  24429.     -- folder. Ignore errors for now, we will check whether the directory 
  24430.     -- is successfully created later on.
  24431.  
  24432.     -- Don't suppress output from xp_cmdshell so user knows what's going on
  24433.     -- in case something goes wrong 
  24434.     SELECT @destination_folder = @destination_folder + @ftporuncdir + '\'
  24435.     SELECT @command = 'mkdir "' + @destination_folder + '"'
  24436.     IF (@platform_nt = 1)
  24437.         SELECT @command = '" ' + @command + ' "'
  24438.     EXEC master..xp_cmdshell @command
  24439.     
  24440.     SELECT @destination_folder = @destination_folder + @pubdir + '\'
  24441.     SELECT @command = 'mkdir "' + @destination_folder + '"'
  24442.     IF (@platform_nt = 1)
  24443.         SELECT @command = '" ' + @command + ' "'
  24444.     EXEC master..xp_cmdshell @command
  24445.  
  24446.     SELECT @destination_folder = @destination_folder + @timestampdir + '\'
  24447.     SELECT @command = 'mkdir "' + @destination_folder + '"'
  24448.     IF (@platform_nt = 1)
  24449.         SELECT @command = '" ' + @command + ' "'
  24450.     EXEC master..xp_cmdshell @command
  24451.  
  24452.     -- Check if the real destination folder exists
  24453.     EXEC sp_MSget_file_existence @destination_folder, @directory_exists OUTPUT
  24454.     IF @directory_exists = 0
  24455.     BEGIN
  24456.         RAISERROR(21288, 16, -1)
  24457.         RETURN (1)
  24458.     END
  24459.  
  24460.     -- Do the actual copying
  24461.     SELECT @command = 'copy "' + @source_folder + '*.*" "' + @destination_folder + '"'    
  24462.     IF (@platform_nt = 1)
  24463.         SELECT @command = '" ' + @command + ' "'
  24464.     
  24465.     EXEC @retcode = master..xp_cmdshell @command
  24466.     
  24467.     IF @retcode <> 0
  24468.         RETURN (1)
  24469.     ELSE
  24470.         RETURN (0)
  24471. END
  24472. go
  24473. EXEC dbo.sp_MS_marksystemobject sp_MScopysnapshot
  24474. go
  24475.  
  24476. raiserror('Creating procedure sp_copymergesnapshot', 0,1)
  24477. go
  24478. CREATE PROCEDURE sp_copymergesnapshot (
  24479.     @publication          sysname,
  24480.     @destination_folder   nvarchar(255)
  24481.     )
  24482. AS
  24483. BEGIN
  24484.     SET NOCOUNT ON
  24485.     DECLARE @retcode       int
  24486.     DECLARE @source_folder nvarchar(255)
  24487.     SELECT @retcode = 0
  24488.     
  24489.     CREATE TABLE #snapshot_folders
  24490.     (
  24491.         id              int identity, 
  24492.         snapshot_folder nvarchar(255) collate database_default
  24493.     )
  24494.     IF @@ERROR <> 0
  24495.     BEGIN
  24496.         RETURN 1
  24497.     END
  24498.  
  24499.     INSERT INTO #snapshot_folders
  24500.     EXEC @retcode = sp_browsemergesnapshotfolder @publication = @publication
  24501.     IF @retcode <> 0 OR @@ERROR <> 0
  24502.     BEGIN
  24503.         GOTO Failure
  24504.     END
  24505.     
  24506.     SELECT @source_folder = (select top 1 snapshot_folder FROM #snapshot_folders ORDER BY id ASC)
  24507.     IF @@ERROR <> 0
  24508.     BEGIN
  24509.         GOTO Failure
  24510.     END        
  24511.     SET ROWCOUNT 0    
  24512.  
  24513.     EXEC @retcode = sp_MScopysnapshot @source_folder,
  24514.                                       @destination_folder
  24515.     IF @retcode <> 0 OR @@ERROR <> 0 
  24516.     BEGIN
  24517.         GOTO Failure
  24518.     END
  24519.  
  24520.     DROP TABLE #snapshot_folders
  24521.     RETURN 0
  24522. Failure:
  24523.     SET ROWCOUNT 0    
  24524.     DROP TABLE #snapshot_folders        
  24525.     RETURN 1
  24526. END
  24527. GO
  24528. EXEC dbo.sp_MS_marksystemobject sp_copymergesnapshot
  24529. go
  24530.  
  24531. raiserror('Creating procedure sp_copysnapshot', 0,1)
  24532. go
  24533. CREATE PROCEDURE sp_copysnapshot (
  24534.     @publication        sysname,
  24535.     @destination_folder nvarchar(255),
  24536.     @subscriber         sysname = NULL,
  24537.     @subscriber_db      sysname = NULL
  24538.     )
  24539. AS
  24540. BEGIN
  24541.     SET NOCOUNT ON
  24542.     DECLARE @retcode       int
  24543.     DECLARE @source_folder nvarchar(255)
  24544.     SELECT @retcode = 0
  24545.     
  24546.     CREATE TABLE #snapshot_folders
  24547.     (
  24548.         id              int identity,
  24549.         snapshot_folder nvarchar(255) collate database_default
  24550.     )
  24551.     IF @@ERROR <> 0
  24552.     BEGIN
  24553.         RETURN 1
  24554.     END
  24555.  
  24556.     INSERT INTO #snapshot_folders
  24557.     EXEC @retcode = sp_browsesnapshotfolder @publication = @publication,
  24558.                                             @subscriber = @subscriber,
  24559.                                             @subscriber_db = @subscriber_db
  24560.     IF @retcode <> 0 OR @@ERROR <> 0
  24561.     BEGIN
  24562.         GOTO Failure
  24563.     END
  24564.  
  24565.     SELECT @source_folder = (select top 1 snapshot_folder FROM #snapshot_folders ORDER BY id)
  24566.     IF @@ERROR <> 0
  24567.     BEGIN
  24568.         GOTO Failure
  24569.     END        
  24570.     SET ROWCOUNT 0
  24571.  
  24572.     EXEC @retcode = sp_MScopysnapshot @source_folder,
  24573.                                       @destination_folder
  24574.     IF @retcode <> 0 OR @@ERROR <> 0 
  24575.     BEGIN
  24576.         GOTO Failure
  24577.     END
  24578.  
  24579.     DROP TABLE #snapshot_folders
  24580.     RETURN 0
  24581. Failure:
  24582.     SET ROWCOUNT 0
  24583.     DROP TABLE #snapshot_folders        
  24584.     RETURN 1
  24585. END
  24586. GO
  24587. EXEC dbo.sp_MS_marksystemobject sp_copysnapshot
  24588. go
  24589.  
  24590. raiserror('Creating procedure sp_MSrepl_validate_dts_package', 0,1)
  24591. go
  24592. CREATE PROCEDURE sp_MSrepl_validate_dts_package (
  24593.     @name sysname
  24594.      ) AS
  24595.  
  24596.     SET NOCOUNT ON
  24597.  
  24598.     /*
  24599.     ** Declarations.
  24600.     */
  24601.     if not exists (select * from msdb.dbo.sysdtspackages where
  24602.         name = @name)
  24603.     begin
  24604.         raiserror(21171, 
  24605.             16, -1, @name, @@servername )
  24606.         return 1
  24607.     end
  24608. go
  24609. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_validate_dts_package
  24610. go
  24611.  
  24612. grant execute on dbo.sp_browsemergesnapshotfolder to public
  24613. go
  24614.  
  24615. grant execute on dbo.sp_browsesnapshotfolder to public
  24616. go
  24617.  
  24618. grant execute on dbo.sp_copymergesnapshot to public
  24619. go
  24620.  
  24621. grant execute on dbo.sp_copysnapshot to public
  24622. go
  24623.  
  24624. grant execute on dbo.sp_MSenum_replsqlqueues to public
  24625. grant execute on dbo.sp_MSenum_replqueues to public
  24626. go
  24627.  
  24628. raiserror('Creating procedure sp_MSget_load_hint', 0,1)
  24629. go
  24630. create procedure sp_MSget_load_hint @objname sysname, @type int
  24631. as
  24632. declare @objid int
  24633. declare @tabname sysname
  24634. declare @tabid int
  24635. declare @hint   nvarchar(2048)
  24636. declare @i int
  24637. declare @thiskey sysname
  24638. declare @indid smallint
  24639. declare @indstat int
  24640.  
  24641. select @objid = object_id( @objname )
  24642.  
  24643. if exists ( select * from sysobjects where id = @objid and type = 'V' )
  24644. begin
  24645.     select @tabid = depid from sysdepends where id = object_id( @objname )
  24646.     select @tabname = object_name( @tabid )
  24647.     
  24648.     select @indid = indid, @indstat = status 
  24649.         from sysindexes where id = @tabid and ( status & @type ) = @type
  24650.     if @indid is not null
  24651.     begin
  24652.         create table #colnames ( idxcolname sysname collate database_default)
  24653.  
  24654.         select @thiskey = index_col( @tabname, @indid, 1 )
  24655.         select @i = 2
  24656.         while (@thiskey is not null )
  24657.         begin
  24658.             insert into #colnames( idxcolname ) values( @thiskey )
  24659.             select @thiskey = index_col(@tabname, @indid, @i)
  24660.             select @i = @i + 1
  24661.         end
  24662.         if exists ( select idxcolname from #colnames 
  24663.                      where idxcolname not in
  24664.                         (select name from syscolumns where id = object_id( @objname ) ) )
  24665.         begin
  24666.             select @tabid = 0
  24667.         end    
  24668.         drop table #colnames
  24669.     end
  24670.     else
  24671.     begin
  24672.         select @tabid = 0
  24673.     end
  24674. end
  24675. else 
  24676. begin
  24677.     select @tabname = @objname
  24678.     select @tabid = object_id( @objname )
  24679.  
  24680.     select @indid = indid, @indstat = status 
  24681.         from sysindexes where id = @tabid and ( status & @type ) = @type
  24682.     if @indid is null
  24683.     begin
  24684.         select @tabid = 0
  24685.     end
  24686. end
  24687.  
  24688. -- Check for computed columns in chosen index. If computed columns exist,
  24689. -- don't return a load hint.
  24690. if @indid is not null
  24691. begin
  24692.     select @i = 1
  24693.     select @thiskey = index_col( @tabname, @indid, @i )
  24694.     while @thiskey is not null
  24695.     begin
  24696.         if isnull( columnproperty( @tabid, @thiskey, 'IsComputed' ), 0 ) = 1
  24697.         begin
  24698.             select @indid = null,
  24699.                    @tabid = 0
  24700.             break
  24701.         end
  24702.         select @i = @i + 1
  24703.         select @thiskey = index_col( @tabname, @indid, @i )
  24704.     end
  24705. end
  24706.  
  24707. if @tabid <> 0
  24708. begin
  24709.     select @hint = 'ORDER( '+QUOTENAME(index_col( @tabname, @indid, 1 )) collate database_default
  24710.     select @thiskey = index_col( @tabname, @indid, 2 ) 
  24711.     select @i = 3
  24712.     while (@thiskey is not null )
  24713.     begin
  24714.         select @hint = @hint + ',' + QUOTENAME(@thiskey) collate database_default
  24715.         select @thiskey = index_col(@tabname, @indid, @i)
  24716.         select @i = @i + 1
  24717.     end
  24718.  
  24719.     select @hint = @hint + ' ASC)'
  24720.  
  24721.     select @hint, @indstat
  24722. end
  24723. GO
  24724.  
  24725. EXEC dbo.sp_MS_marksystemobject sp_MSget_load_hint
  24726. go
  24727.  
  24728. grant execute on dbo.sp_MSget_load_hint to public
  24729. go
  24730.  
  24731. raiserror('Creating procedure sp_getsubscriptiondtspackagename', 0,1)
  24732. go
  24733. CREATE PROCEDURE sp_getsubscriptiondtspackagename (
  24734.     @publication sysname,
  24735.     @subscriber sysname = NULL
  24736.      ) AS
  24737.  
  24738.     SET NOCOUNT ON
  24739.  
  24740.     declare @name sysname
  24741.     declare @name_full sysname
  24742.     declare @id    int
  24743.     
  24744.     select @id = 1
  24745.     select @name = @publication
  24746.     if @subscriber is not null
  24747.         select @name = @name + N'_' + @subscriber
  24748.  
  24749.     -- reserver space for numbers to make the name unique
  24750.     select @name = substring(@name, 1, 100)
  24751.     select @name_full = @name
  24752.  
  24753.     while (1=1)
  24754.     begin
  24755.         if not exists (select * from msdb.dbo.sysdtspackages where
  24756.             name = @name_full)
  24757.             break
  24758.         select @name_full = @name + '_' + convert(nvarchar(10), @id)
  24759.         select @id = @id + 1
  24760.     end
  24761.     select N'new_package_name' = @name_full
  24762. go
  24763.  
  24764. EXEC dbo.sp_MS_marksystemobject sp_getsubscriptiondtspackagename
  24765. go
  24766.  
  24767. grant execute on dbo.sp_getsubscriptiondtspackagename to public
  24768. go
  24769.  
  24770. raiserror('Creating procedure sp_MSverifytranfilter', 0, 1)
  24771. GO
  24772. create procedure sp_MSverifytranfilter @objid int
  24773. as
  24774. DECLARE @artname sysname
  24775. DECLARE @sync_objid int
  24776. DECLARE @qual_sync_object nvarchar(1024)
  24777.  
  24778. DECLARE #testcursor CURSOR LOCAL FAST_FORWARD for
  24779.     SELECT name, sync_objid from sysarticles
  24780.     WHERE  objid = @objid
  24781.     
  24782. open #testcursor
  24783. fetch #testcursor into @artname, @sync_objid
  24784. while @@fetch_status <> -1
  24785. begin
  24786.     select @qual_sync_object = quotename( user_name(objectproperty(@sync_objid,'OwnerId'))) collate database_default + N'.' + quotename(object_name(@sync_objid)) collate database_default
  24787.  
  24788.     exec ( N'declare @var int select @var = count(*) from '+ @qual_sync_object + N' where 0 = 1' )
  24789.  
  24790.     if @@ERROR<> 0
  24791.     BEGIN
  24792.         raiserror( 14090, 16, -1, @artname )
  24793.         return 1
  24794.     END
  24795.     fetch #testcursor into @artname, @sync_objid
  24796. end
  24797. close #testcursor
  24798. deallocate #testcursor
  24799. return 0
  24800. GO
  24801.  
  24802. EXEC dbo.sp_MS_marksystemobject sp_MSverifytranfilter
  24803. go
  24804.  
  24805.  
  24806. raiserror('Creating procedure sp_repldropcolumn', 0,1)
  24807. GO
  24808.  
  24809. CREATE PROCEDURE sp_repldropcolumn(
  24810.     @source_object      nvarchar(270),
  24811.     @column                sysname,
  24812.     @from_agent            int = 0, 
  24813.     @schema_change_script nvarchar(4000) = NULL,
  24814.     @force_invalidate_snapshot bit = 1,    /* Force invalidate existing snapshot */
  24815.     @force_reinit_subscription bit = 0    /* Force reinit subscription */
  24816.  
  24817.     )
  24818. as
  24819.  
  24820. set nocount on
  24821. declare @objid            int
  24822. declare @at_publisher    bit
  24823. declare @pubname        sysname
  24824. declare @artname        sysname
  24825. declare @tran_pubname    sysname
  24826. declare @tran_artname    sysname
  24827. declare @tran_artid        int
  24828. declare @tran_pubid        int
  24829. declare @colid            int
  24830. declare @missing_index    int
  24831. declare @tablename        sysname
  24832. declare @pubid            uniqueidentifier
  24833. declare @artid            uniqueidentifier
  24834. declare @partitioned    int
  24835. declare @missing_count    int
  24836. declare @missing_bm        varbinary(32)
  24837. declare @old_missing_bm    varbinary(32)
  24838. declare @schematext        nvarchar(4000)
  24839. declare @schemaversion    int
  24840. declare @not_for_merge    bit
  24841. declare @qual_source_object nvarchar(262)
  24842. declare @qual_dest_object nvarchar(262)
  24843. declare @schematype        int
  24844. declare @schemaguid        uniqueidentifier
  24845. declare @conflict_table    sysname
  24846. declare @ins_conflict_proc sysname
  24847. declare @publisher        sysname
  24848. declare @publisher_db    sysname
  24849. declare @command        nvarchar(3000)
  24850. declare @sync_objid        int
  24851. declare @retcode         int
  24852. declare @snapshot_ready int
  24853. declare @con_id            int
  24854. declare @dest_owner        sysname
  24855. declare @dest_object    nvarchar(386)
  24856. declare @owner            sysname
  24857. declare @columnbm        varbinary(128)
  24858. declare @in_partition    int
  24859. declare @merge_pub_object_bit    int
  24860. declare @is_for_merge    bit
  24861. declare @is_for_tran    bit
  24862. declare @no_schema_replication bit
  24863. declare @servername        sysname
  24864. declare @dbname            sysname
  24865. declare @con_name        sysname
  24866. declare @v_unique_index    int
  24867. declare @qual_column        nvarchar(140)
  24868. declare @indid                int
  24869. declare @index_cnt             int
  24870. declare @pkkey                sysname
  24871. declare @v_unique_constraint    int
  24872. declare @merge_pub_unmarkcolumn_bit    int
  24873. declare @merge_pub_markcolumn_bit    int
  24874. declare @schema_start_lsn binary(10)
  24875. declare @schema_end_lsn binary(10)
  24876.  
  24877. /*
  24878. ** Security Check
  24879. */
  24880. EXEC @retcode = dbo.sp_MSreplcheck_publish
  24881. IF @@ERROR <> 0 or @retcode <> 0
  24882.     return (1)
  24883.  
  24884. -- check to see if this stored procedure is called via replication agent.
  24885. if sessionproperty('replication_agent')<>1
  24886.     select @from_agent = 0
  24887. else
  24888.     select @from_agent = 1
  24889. select @merge_pub_markcolumn_bit = 0x4000
  24890. select @merge_pub_unmarkcolumn_bit = ~@merge_pub_markcolumn_bit
  24891. select @v_unique_constraint = 4096
  24892. select @v_unique_index      = 2         -- status in sysindexes
  24893.  
  24894. select @qual_column=QUOTENAME(@column)
  24895.  
  24896. select @no_schema_replication = 0
  24897. select @not_for_merge    = 0
  24898. select @merge_pub_object_bit     = 128
  24899. select @objid = object_id(@source_object)
  24900. select @servername=@@SERVERNAME
  24901. select @dbname=db_name()
  24902.  
  24903. if @objid is NULL
  24904. begin
  24905.     --if table does not exists and the SP is called from replication agent, ignore the error and exit with success.
  24906.     if @from_agent=1
  24907.         return (0)
  24908.     else
  24909.         begin
  24910.             raiserror(14027, 16, -1, @source_object)
  24911.             return (1)
  24912.         end
  24913. end
  24914.  
  24915. if not exists (select * from syscolumns where name=@column and id=@objid)
  24916. begin
  24917.     if @from_agent=0
  24918.     begin
  24919.         raiserror(21166, 16, -1, @column)
  24920.         return (1)
  24921.     end
  24922.     else
  24923.         return (0)
  24924. end
  24925.  
  24926. select @indid = indid from sysindexes where id = @objid and (status & 2048) <> 0    /* PK index */
  24927. select @index_cnt = 1
  24928. while (@index_cnt <= 16)
  24929. begin
  24930.     select @pkkey = INDEX_COL(@source_object, @indid, @index_cnt)
  24931.     if @pkkey is NULL
  24932.         break
  24933.     if @pkkey=@column
  24934.     begin
  24935.         raiserror(21264, 16, -1, @column, @source_object)
  24936.         return (1)
  24937.     end
  24938.     select @index_cnt = @index_cnt + 1
  24939. end
  24940.     
  24941. /*
  24942. ** Check for unique index defined on this column - to disallow such a column from being dropped
  24943. */    
  24944. if exists (select * from sysindexes where id=@objid 
  24945.     and (status & @v_unique_index = @v_unique_index 
  24946.             or status & @v_unique_constraint = @v_unique_constraint))
  24947. begin
  24948.     declare @keys varbinary(816)
  24949.     declare @i         int
  24950.     declare #check_unique CURSOR LOCAL FAST_FORWARD for 
  24951.         select indid from sysindexes where id=@objid 
  24952.                 and (status & @v_unique_index = @v_unique_index 
  24953.                     or status & @v_unique_constraint = @v_unique_constraint)
  24954.     open #check_unique
  24955.     fetch #check_unique into @indid
  24956.     while (@@fetch_status<>-1)
  24957.     begin
  24958.         SELECT @i = 1
  24959.         WHILE (@i <= 16)
  24960.         BEGIN
  24961.             SELECT @pkkey = INDEX_COL(@source_object, @indid, @i)
  24962.             if @pkkey is NULL
  24963.                 break
  24964.             if @pkkey=@column
  24965.             BEGIN
  24966.                 raiserror(21265, 16, -1, @column, @source_object)
  24967.                 close #check_unique
  24968.                 deallocate #check_unique
  24969.                 return (1)
  24970.             END
  24971.             select @i = @i + 1
  24972.         END    
  24973.         fetch #check_unique into @indid
  24974.     end
  24975.     close #check_unique
  24976.     deallocate #check_unique
  24977. end
  24978.  
  24979. if exists (select * from sysobjects where name='sysmergearticles')
  24980. begin
  24981.     if @from_agent=0 and exists (select * from sysmergearticles where objid=@objid and pubid not in 
  24982.         (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@@SERVERNAME) and publisher_db=db_name()))
  24983.     begin
  24984.         raiserror(21260, 16, -1, @dbname, @servername, @source_object)
  24985.         return (1)
  24986.     end
  24987. end
  24988.  
  24989. -- if not for TRAN, it has to be a merge publication
  24990. if not exists (select * from sysobjects where name='syspublications')
  24991. begin
  24992.     if not exists (select * from sysmergearticles where objid=@objid)
  24993.         select @no_schema_replication = 1
  24994. end
  24995.  
  24996. -- if not for merge, it has to be a tran publication
  24997. if not exists (select * from sysobjects where name='sysmergepublications')
  24998. begin
  24999.     if not exists (select * from sysarticles where objid=@objid)
  25000.         select @no_schema_replication =1
  25001. end
  25002.  
  25003. if exists (select * from sysobjects where name='sysmergepublications')
  25004.     and exists (select * from sysobjects where name='syspublications')
  25005. begin
  25006.     if not exists (select * from sysarticles where objid=@objid)
  25007.             and not exists (select * from sysmergearticles where objid=@objid)
  25008.         select @no_schema_replication=1
  25009. end
  25010.  
  25011. if @no_schema_replication=1
  25012.     begin
  25013.         raiserror(21246, 16, -1, @source_object)
  25014.         return (1)
  25015.     end
  25016.  
  25017. if exists (select * from sysobjects where name = 'sysmergearticles')
  25018. begin
  25019.     if exists  (select * from sysmergearticles where objid=@objid)
  25020.         select @is_for_merge=1
  25021.     else
  25022.         select @is_for_merge=0
  25023. end
  25024. else
  25025.     select @is_for_merge=0
  25026.  
  25027. -- PARSENAME VARS
  25028.     declare      @UnqualName      sysname  --rightmost name node
  25029.     declare      @QualName1       sysname  
  25030. -- END PARSENAME VARS
  25031.  
  25032.     select @UnqualName = PARSENAME(@source_object, 1)
  25033.     select @QualName1 = PARSENAME(@source_object, 2)
  25034.     if @UnqualName IS NULL
  25035.          return 1
  25036.     if @QualName1 is not NULL
  25037.         select @owner = @QualName1
  25038.             else select @owner=user_name(uid) from dbo.sysobjects where id = @objid
  25039.  
  25040. select @tablename = @UnqualName
  25041. select @qual_source_object = QUOTENAME(@owner) + N'.' + QUOTENAME(@tablename)
  25042. select @at_publisher = 0
  25043. select @colid=colid from dbo.syscolumns where id=@objid and name=@column
  25044. if @colid is NULL
  25045.     begin
  25046.         raiserror(21166, 16, -1, @column)
  25047.         return (1)
  25048.     end
  25049.  
  25050. /*
  25051. ** Considering holes, colid is not necessarily the one in bitmap. Get this value from count(*)
  25052. */
  25053. select @missing_index = count(*) from dbo.syscolumns where id=@objid and colid<=@colid
  25054. begin TRAN
  25055. save tran sp_repldropcolumn
  25056.     if @is_for_merge=1
  25057.     begin
  25058.         exec sp_replupdateschema @qual_source_object
  25059.         if @@ERROR<>0
  25060.             goto FAILURE
  25061.         exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  25062.         if @retcode<>0 or @@ERROR<>0
  25063.             goto FAILURE
  25064.         --unmark this column so that it can be dropped
  25065.         update dbo.syscolumns set colstat=colstat & @merge_pub_unmarkcolumn_bit where id=@objid and colid = @colid
  25066.         if @@ERROR<>0 
  25067.             goto FAILURE
  25068.     end
  25069.  
  25070.  
  25071.     select @is_for_tran = 0    
  25072.     if exists (select * from dbo.sysobjects where name='sysarticles')
  25073.     begin
  25074.         if exists (select * from dbo.sysarticles where objid=@objid)
  25075.         begin
  25076.             if exists (SELECT P.pubid FROM dbo.syspublications P, dbo.sysarticles A, dbo.syssubscriptions S 
  25077.                     WHERE A.objid = @objid    and A.pubid = P.pubid and A.artid = S.artid
  25078.                         and (P.allow_sync_tran = 1 or P.allow_queued_tran = 1) 
  25079.                         and S.status = 2  -- active
  25080.                         and S.sync_type != 2 -- not 'none'
  25081.                         and S.update_mode != 0 ) -- not 'read only'
  25082.              and @force_reinit_subscription = 0
  25083.             begin 
  25084.                 raiserror(21381, 16, -1, @tablename)
  25085.                 goto FAILURE
  25086.             end
  25087.  
  25088.             select @is_for_tran =1
  25089.             select pubid, artid, columns 
  25090.                 into #oldcols 
  25091.                 from sysarticles
  25092.                 where objid = @objid
  25093.         end
  25094.     end
  25095.  
  25096.     /*
  25097.     ** First call TRAN Level stored procedure to 
  25098.     */
  25099.     if @is_for_tran = 1
  25100.     begin
  25101.         exec @retcode = sp_MSprep_exclusive @qual_source_object
  25102.         if @@ERROR<>0 or @retcode <> 0
  25103.             goto FAILURE
  25104.  
  25105.         exec @retcode = sp_replincrementlsn @schema_start_lsn OUTPUT
  25106.         if @@ERROR<>0 or @retcode <> 0
  25107.             goto FAILURE
  25108.  
  25109.         exec @retcode = sp_replpostschema @objid
  25110.         if @@ERROR<>0 or @retcode <> 0
  25111.             goto FAILURE
  25112.  
  25113.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  25114.             select a.artid, p.name from sysarticles a, syspublications p where a.objid=@objid
  25115.                     and p.pubid = a.pubid
  25116.         open #trancolumn
  25117.         fetch #trancolumn into @tran_artid, @tran_pubname
  25118.         while (@@fetch_status <> -1)
  25119.         BEGIN
  25120.             select @tran_artname=name from sysarticles where artid=@tran_artid
  25121.             exec @retcode = sp_articlecolumn @publication = @tran_pubname, @article = @tran_artname, @column = @column, 
  25122.                          @operation = 'drop', @change_active = 2
  25123.                         ,@force_invalidate_snapshot = 1
  25124.                         ,@force_reinit_subscription = 1
  25125.             if @retcode <>0 or @@ERROR<>0
  25126.                 goto DROPTRAN
  25127.             fetch #trancolumn into @tran_artid, @tran_pubname            
  25128.         END
  25129.         close #trancolumn
  25130.         deallocate #trancolumn
  25131.     end
  25132.  
  25133.     if not exists (select * from sysobjects where name='sysmergearticles')
  25134.         select @not_for_merge = 1
  25135.     else
  25136.         if not exists (select * from sysmergearticles where objid=@objid)
  25137.             select @not_for_merge =1
  25138.     
  25139.             
  25140.     if @not_for_merge = 1 
  25141.     begin
  25142.         if exists (select * from syscolumns where name=@column and id =@objid)
  25143.         begin
  25144.             exec ('alter table '+ @qual_source_object + ' drop column ' + @qual_column )
  25145.                     if @@ERROR<>0
  25146.                         goto FAILURE
  25147.             
  25148.             exec @retcode = sp_MSverifytranfilter @objid
  25149.             if @@ERROR <> 0 or @retcode <> 0
  25150.             begin
  25151.                 goto FAILURE
  25152.             end                    
  25153.         end
  25154.     end
  25155.     else
  25156.     begin
  25157.         if exists (select * from sysmergepublications where pubid in 
  25158.             (select pubid from sysmergearticles where objid=@objid) and snapshot_ready=0)
  25159.             and exists (select * from syscolumns where name=@column and id =@objid)
  25160.             begin
  25161.                 declare #nosnapshot CURSOR LOCAL FAST_FORWARD for
  25162.                     select p.name, a.name from sysmergepublications p, sysmergearticles a 
  25163.                         where p.pubid=a.pubid and a.objid=@objid and p.snapshot_ready=0
  25164.                 open #nosnapshot
  25165.                 fetch #nosnapshot into @pubname, @artname
  25166.                 while (@@fetch_status<>-1)
  25167.                 begin
  25168.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'drop', 'true'
  25169.                     if @retcode <>0 or @@ERROR<>0
  25170.                         goto ERROR_EXIT
  25171.                     fetch #nosnapshot into @pubname, @artname
  25172.                 end
  25173.                 close #nosnapshot
  25174.                 deallocate #nosnapshot
  25175.             end
  25176.  
  25177.         declare #dropcolumn_schema CURSOR LOCAL FAST_FORWARD fast_forward for 
  25178.                 select name, pubid, artid, destination_owner, columns from sysmergearticles where objid=@objid and pubid
  25179.                             in (select pubid from sysmergepublications where snapshot_ready>0) order by pubid ASC
  25180.         open #dropcolumn_schema
  25181.         fetch #dropcolumn_schema into @artname, @pubid, @artid, @dest_owner, @columnbm
  25182.         while (@@fetch_status <> -1)
  25183.         BEGIN
  25184.                 if @dest_owner is not NULL
  25185.                     select @dest_object = QUOTENAME(@dest_owner) + N'.' + QUOTENAME(@tablename)
  25186.                 else
  25187.                     select @dest_object = QUOTENAME(@tablename)
  25188.  
  25189.                 exec @in_partition = sp_MStestbit @bm=@columnbm, @coltotest=@colid
  25190.  
  25191.                 select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  25192.                     from sysmergepublications where pubid=@pubid
  25193.                 select @at_publisher=0
  25194.                 if @publisher=@@SERVERNAME and @publisher_db=db_name() and @in_partition<>0
  25195.                 begin
  25196.                     select @at_publisher=1
  25197.                     select @schematext = 'exec sp_repldropcolumn ''' + @dest_object + ''', ''' + @column + ''', 1'
  25198.                     select @schemaversion = schemaversion from sysmergeschemachange
  25199.                     if (@schemaversion is NULL)
  25200.                         set @schemaversion = 1
  25201.                     else
  25202.                         select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  25203.                     set @schemaguid = newid()
  25204.                     set @schematype = 11 /* alter table */
  25205.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'drop', 'true'
  25206.                     if @retcode<>0 or @@ERROR<>0
  25207.                         goto INNER_FAIL2 -- need to deallocate cursor for this loop.
  25208.                     exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  25209.                     if @@ERROR<>0 or @retcode<>0 
  25210.                         goto INNER_FAIL2
  25211.                         
  25212.                     select @schematext = 'alter table ' +  @dest_object + ' drop column ' + @column 
  25213.                     select @schemaversion = @schemaversion + 1
  25214.                     set @schematype = 13 -- for Jet use only
  25215.                     set @schemaguid = newid()
  25216.                     exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext                        
  25217.                     if @@ERROR<>0 or @retcode<>0 
  25218.                         goto INNER_FAIL2
  25219.                 end
  25220.             fetch #dropcolumn_schema into @artname, @pubid, @artid, @dest_owner, @columnbm
  25221.         END
  25222.         close #dropcolumn_schema
  25223.         deallocate #dropcolumn_schema
  25224.  
  25225.         /* drop the column only once */
  25226.         if exists (select  *  from syscolumns where id=@objid and name=@column)
  25227.         begin
  25228.             select @command = 'alter table ' + @qual_source_object + ' drop column ' + @qual_column
  25229.             exec (@command)
  25230.             if @@ERROR<>0
  25231.                 GOTO INNER_FAIL
  25232.  
  25233.             -- if transactionally replicated, verify that filter columns weren't dropped
  25234.  
  25235.             if( @is_for_tran = 1 )
  25236.             begin
  25237.                 exec @retcode = sp_MSverifytranfilter @objid
  25238.                 if @@ERROR <> 0 or @retcode <> 0
  25239.                 begin
  25240.                     goto FAILURE
  25241.                 end                    
  25242.             end
  25243.         end
  25244.         declare #dropcolumn CURSOR LOCAL FAST_FORWARD fast_forward for 
  25245.                 select pubid, name, sync_objid, artid, missing_col_count, missing_cols, 
  25246.                     conflict_table, ins_conflict_proc from sysmergearticles where objid=@objid and pubid
  25247.                             in (select pubid from sysmergepublications where snapshot_ready>0) order by pubid ASC
  25248.         open #dropcolumn
  25249.         fetch #dropcolumn into @pubid, @artname, @sync_objid, @artid, 
  25250.                 @missing_count, @missing_bm, @conflict_table, @ins_conflict_proc
  25251.         while (@@fetch_status <> -1)
  25252.         BEGIN                
  25253.             select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  25254.                 from sysmergepublications where pubid=@pubid
  25255.             select @at_publisher=0
  25256.             if @publisher=@@SERVERNAME and @publisher_db=db_name()
  25257.                 select @at_publisher=1
  25258.  
  25259.             if @conflict_table is not NULL 
  25260.             begin
  25261.                 select @con_id = object_id(@conflict_table)
  25262.                 if @con_id is NULL
  25263.                 begin
  25264.                     raiserror(21286, 16, -1, @conflict_table)
  25265.                     GOTO INNER_FAIL
  25266.                 end
  25267.  
  25268.             select @colid=colid from syscolumns where id = @con_id and name=@column            
  25269.             
  25270.     
  25271.                 if exists (select name from syscolumns where name=@column and id=@con_id)
  25272.                 begin
  25273.                     select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' drop column ' + @qual_column
  25274.                     exec (@command)
  25275.                     if @@ERROR<>0
  25276.                         goto INNER_FAIL
  25277.                 end
  25278.             end
  25279.  
  25280.             /*
  25281.             ** Force the re-generation of conflict insert table cause the schema is changed for sure
  25282.             */
  25283.             if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL
  25284.             begin
  25285.                 exec ('drop procedure ' + @ins_conflict_proc)
  25286.                 if @@ERROR<>0
  25287.                     goto INNER_FAIL
  25288.                 update sysmergearticles set ins_conflict_proc=NULL where pubid=@pubid and artid=@artid
  25289.                 if @@ERROR<>0
  25290.                     goto INNER_FAIL
  25291.             end
  25292.     
  25293.             if @at_publisher=1
  25294.             begin
  25295.                 exec @retcode = sp_MSpublicationview @pubname, 1
  25296.                 if @retcode<>0 or @@ERROR<>0
  25297.                 begin
  25298.                     raiserror(21201, 16, -1) 
  25299.                     goto INNER_FAIL
  25300.                 end
  25301.             end
  25302.             select @missing_count=@missing_count + 1
  25303.             select @old_missing_bm=@missing_bm
  25304.             exec @retcode=sp_MSsetbit @missing_bm OUTPUT, @missing_index
  25305.             if @retcode<>0 or @@ERROR<>0
  25306.                 goto INNER_FAIL
  25307.             --if no change, that is, the column is already marked as missing, do not increase 
  25308.             --its count
  25309.             if @missing_bm<>@old_missing_bm
  25310.             begin
  25311.                 update sysmergearticles set missing_col_count=@missing_count, missing_cols=@missing_bm
  25312.                     where pubid=@pubid and artid=@artid
  25313.                 if @@ERROR<>0
  25314.                 goto INNER_FAIL
  25315.             end
  25316.             
  25317.                 
  25318.             exec @retcode = sp_MSdroparticletriggers @qual_source_object
  25319.             if @retcode<>0 or @@ERROR<>0
  25320.                 goto INNER_FAIL
  25321.             exec @retcode = sp_MSaddmergetriggers @qual_source_object
  25322.             if @retcode<>0 or @@ERROR<>0
  25323.                 goto INNER_FAIL
  25324.             exec @retcode = sp_MSsetartprocs @publication=@pubname, @article=@artname, @force_flag=1
  25325.             if @retcode<>0 or @@ERROR<>0
  25326.                 goto INNER_FAIL
  25327.             /*
  25328.             ** passing in one more parameter to sp_MSgetconflictinsertproc such that there is 
  25329.             ** no select statement at the end of that SP as needed else where. The default is 1.
  25330.             */
  25331.             exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0
  25332.             if @retcode<>0 or @@ERROR<>0
  25333.                 goto INNER_FAIL
  25334.  
  25335.             fetch #dropcolumn into @pubid, @artname, @sync_objid, @artid, 
  25336.                 @missing_count, @missing_bm, @conflict_table, @ins_conflict_proc
  25337.         END
  25338.         CLOSE #dropcolumn
  25339.         DEALLOCATE #dropcolumn
  25340.     
  25341.         if @is_for_merge=1
  25342.         begin
  25343.             exec @retcode = sp_MSmarkreplinfo @tablename, @owner
  25344.             if @retcode<>0 or @@ERROR<>0
  25345.                 goto FAILURE
  25346.         end
  25347.     end
  25348.  
  25349. -- finally, if it's transactional, trigger a reinit
  25350. if @is_for_tran = 1
  25351. begin
  25352.  
  25353.     if exists (select * from sysarticles where objid = @objid)
  25354.     begin
  25355.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  25356.             select a.artid, p.name 
  25357.             from sysarticles a, syspublications p, #oldcols oc
  25358.             where a.objid=@objid
  25359.             and p.pubid = a.pubid
  25360.             and oc.artid = a.artid
  25361.             and oc.columns <> a.columns
  25362.  
  25363.         open #trancolumn
  25364.         fetch #trancolumn into @tran_artid, @tran_pubname
  25365.         while (@@fetch_status <> -1)
  25366.         BEGIN
  25367.             select @tran_artname=name, @tran_pubid = pubid, @owner = dest_owner, @tablename = dest_table from sysarticles where artid=@tran_artid
  25368.             if(@force_reinit_subscription = 0)
  25369.             begin 
  25370.                 if(@owner is not NULL) and (len(@owner) > 0)
  25371.                     select @qual_dest_object = QUOTENAME(@owner) + N'.' 
  25372.                 else 
  25373.                     select @qual_dest_object = N'' 
  25374.                 if(@tablename is not null) and (len(@tablename) > 0)
  25375.                     select @qual_dest_object = @qual_dest_object + QUOTENAME(@tablename)
  25376.                 else 
  25377.                     select @qual_dest_object = @qual_source_object
  25378.                 exec @retcode = sp_MSrepl_schema @pubname = @tran_pubname 
  25379.                             ,@artid = @tran_artid
  25380.                             ,@qual_source_object = @qual_dest_object
  25381.                             ,@column = @column
  25382.                             ,@operation = 1 -- 0 is add, 1 is delete
  25383.                             ,@schema_change_script = @schema_change_script
  25384.                 if @retcode <>0 or @@ERROR<>0
  25385.                     goto DROPTRAN
  25386.             end
  25387.             exec @retcode = dbo.sp_MSreinit_article 
  25388.                             @publication = @tran_pubname
  25389.                             ,@article = @tran_artname
  25390.                             ,@need_new_snapshot = @force_invalidate_snapshot
  25391.                             ,@need_reinit_subscription = @force_reinit_subscription
  25392.                             ,@force_invalidate_snapshot = @force_invalidate_snapshot
  25393.                             ,@force_reinit_subscription = @force_reinit_subscription
  25394.             if @retcode <>0 or @@ERROR<>0
  25395.                 goto DROPTRAN
  25396.             fetch #trancolumn into @tran_artid, @tran_pubname            
  25397.         END
  25398.         close #trancolumn
  25399.         deallocate #trancolumn
  25400.          exec @retcode = sp_replincrementlsn @schema_end_lsn OUTPUT
  25401.          if @@ERROR<>0 or @retcode <> 0
  25402.              goto FAILURE
  25403.          if (@schema_start_lsn is not null) and (@schema_end_lsn is not null)
  25404.          begin
  25405.              insert systranschemas (tabid, startlsn, endlsn) values (@objid, @schema_start_lsn, @schema_end_lsn)
  25406.              if @@ERROR<>0
  25407.                  goto FAILURE
  25408.              exec @retcode = sp_replflush @objid, @schema_start_lsn, @schema_end_lsn
  25409.              if @@ERROR<>0 or @retcode <> 0
  25410.                  goto FAILURE
  25411.          end
  25412.          else
  25413.              goto FAILURE
  25414.     end
  25415. end
  25416.  
  25417.  
  25418. COMMIT TRAN
  25419. return (0)
  25420.  
  25421. DROPTRAN:
  25422. CLOSE #trancolumn
  25423. DEALLOCATE #trancolumn
  25424. GOTO FAILURE
  25425.  
  25426. INNER_FAIL:
  25427. CLOSE #dropcolumn
  25428. DEALLOCATE #dropcolumn
  25429. GOTO FAILURE
  25430.  
  25431. INNER_FAIL2:
  25432. CLOSE #dropcolumn_schema
  25433. DEALLOCATE #dropcolumn_schema
  25434. GOTO FAILURE
  25435.  
  25436.  
  25437. ERROR_EXIT:
  25438. CLOSE #nosnapshot
  25439. DEALLOCATE #nosnapshot
  25440.  
  25441. FAILURE:
  25442.     rollback tran sp_repldropcolumn
  25443.     commit tran
  25444.     raiserror(21284, 16, -1, @column, @source_object)
  25445.     return (1)    
  25446. go
  25447.  
  25448. exec dbo.sp_MS_marksystemobject sp_repldropcolumn 
  25449. go
  25450. raiserror('Creating procedure sp_repladdcolumn', 0,1)
  25451. GO
  25452.  
  25453. CREATE PROCEDURE sp_repladdcolumn(
  25454.     @source_object          nvarchar (358),
  25455.     @column                    sysname,
  25456.     @typetext                 nvarchar(3000),
  25457.     @publication_to_add        nvarchar(4000) = 'all',
  25458.     @from_agent                int = 0, 
  25459.     @schema_change_script    nvarchar(4000) = NULL,
  25460.     @force_invalidate_snapshot bit = 1,    /* Force invalidate existing snapshot */
  25461.     @force_reinit_subscription bit = 0    /* Force reinit subscription */
  25462.     )
  25463. as
  25464. set nocount on
  25465. declare @objid            int
  25466. declare @pubid            uniqueidentifier
  25467. declare @retcode        int
  25468. declare @partitioned    int
  25469. declare @at_publisher    bit
  25470. declare @pubname        sysname
  25471. declare @artname        sysname
  25472. declare @colid            int
  25473. declare @tablename        sysname
  25474. declare @artid            uniqueidentifier
  25475. declare @tran_artid        int
  25476. declare @tran_pubid        int
  25477. declare @schematext        nvarchar(4000)
  25478. declare @schemaversion    int
  25479. declare @schematype        int
  25480. declare @schemaguid        uniqueidentifier
  25481. declare @conflict_table    sysname
  25482. declare @ins_conflict_proc sysname
  25483. declare @publisher        sysname
  25484. declare @qual_column    nvarchar(140)
  25485. declare @not_for_merge    int
  25486. declare @publisher_db    sysname
  25487. declare @command        nvarchar(3000)
  25488. declare @sync_objid        int
  25489. declare @con_id            int
  25490. declare @owner            sysname
  25491. declare @dest_owner        sysname
  25492. declare @dest_object    nvarchar(386)
  25493. declare @merge_pub_object_bit    int
  25494. declare @is_for_merge    bit
  25495. declare @is_for_tran    bit
  25496. declare @dbname            sysname
  25497. declare @servername        sysname
  25498. declare @no_publication bit
  25499. declare @no_schema_replication bit
  25500. declare @qual_source_object nvarchar(362)
  25501. declare @len             int
  25502. declare @prec             int
  25503. declare @scale int
  25504. declare @typename nvarchar(270)
  25505. declare @qual_dest_object nvarchar(362)
  25506. declare @invalid_datatype    bit
  25507. declare @is_identity_or_timestamp bit
  25508. declare @xtype         int
  25509. declare @iscomputed bit
  25510. declare @pass_to_heterogenious bit
  25511. declare @merge_pub_markcolumn_bit    int
  25512. declare @schema_start_lsn binary(10)
  25513. declare @schema_end_lsn binary(10)
  25514. declare @nickname         int
  25515. declare @columns_in_partition    int
  25516. /*
  25517. ** Security Check
  25518. */
  25519. EXEC @retcode = dbo.sp_MSreplcheck_publish
  25520. IF @@ERROR <> 0 or @retcode <> 0
  25521.     return (1)
  25522.  
  25523.  
  25524. select @qual_column=QUOTENAME(@column)
  25525. select @merge_pub_markcolumn_bit = 0x4000
  25526.  
  25527. select @objid = object_id(@source_object)
  25528.  
  25529. -- check to see if this stored procedure is called via replication agent.
  25530. if sessionproperty('replication_agent')<>1
  25531.     select @from_agent = 0
  25532. else
  25533.     begin --if table does not exists and the SP is called from replication agent, ignore the error and exit with success.
  25534.         select @from_agent = 1
  25535.         if @objid is NULL
  25536.             return (0)
  25537.     end
  25538.  
  25539. if @objid is NULL
  25540. begin
  25541.     raiserror(14027, 16, -1, @source_object)
  25542.     return (1)
  25543. end
  25544.  
  25545. if exists (select * from syscolumns where id=@objid and name=@column)
  25546. begin
  25547.     if @from_agent=0
  25548.     begin
  25549.         raiserror(21255, 16, -1, @column, @source_object)
  25550.         return (1)
  25551.     end
  25552.     else
  25553.         return (0)
  25554. end
  25555.  
  25556.  
  25557. -- PARSENAME VARS
  25558.     declare      @UnqualName      sysname  --rightmost name node
  25559.     declare      @QualName1       sysname  
  25560. -- END PARSENAME VARS
  25561.  
  25562.     select @UnqualName = PARSENAME(@source_object, 1)
  25563.     select @QualName1 = PARSENAME(@source_object, 2)
  25564.     if @UnqualName IS NULL
  25565.          return 1
  25566.     if @QualName1 is not NULL
  25567.         select @owner = @QualName1
  25568.             else select @owner=user_name(uid) from sysobjects where id = @objid
  25569.     select @tablename = @UnqualName
  25570.  
  25571.     select @qual_source_object = QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
  25572. select @no_schema_replication = 0
  25573. select @no_publication=0
  25574. select @servername=@@SERVERNAME
  25575. select @dbname=db_name()
  25576. select @merge_pub_object_bit     = 128
  25577. select @not_for_merge = 0
  25578.  
  25579. if exists (select * from sysobjects where name='sysmergearticles')
  25580. begin
  25581.     if @from_agent=0 and exists (select * from sysmergearticles where objid=@objid and pubid not in 
  25582.         (select pubid from sysmergepublications where LOWER(publisher)=LOWER(@servername) and publisher_db=@dbname))
  25583.     begin
  25584.         raiserror(21260, 16, -1, @dbname, @servername, @source_object)
  25585.         return (1)
  25586.     end
  25587. end
  25588.  
  25589. select @invalid_datatype=0
  25590.  
  25591. /* the transaction below is just an experiment to validate type text */
  25592. BEGIN TRAN
  25593. SAVE TRANSACTION fake_move
  25594.     exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  25595.     if @retcode<>0 or @@ERROR<>0
  25596.     begin
  25597.         goto CHECKING_DONE
  25598.     end
  25599.     declare @temp_id         int
  25600.     declare @temp_colid     int
  25601.     select @is_identity_or_timestamp = 0
  25602.     exec ('alter table ' + @qual_source_object + ' add ' + @qual_column + ' ' + @typetext)
  25603.     select @temp_id = object_id(@qual_source_object)
  25604.     if @temp_id is NULL
  25605.     begin
  25606.         raiserror(21285, 16, -1, @column, @source_object)
  25607.         select @invalid_datatype = 1
  25608.         GOTO CHECKING_DONE
  25609.     end
  25610.     select @pass_to_heterogenious=0, @temp_colid = colid, @xtype=xtype, @iscomputed=iscomputed 
  25611.         from syscolumns where id = @temp_id and name=@column
  25612.     if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
  25613.         select @pass_to_heterogenious=1
  25614.     if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 1 or type_name(@xtype) = 'timestamp'
  25615.         select @is_identity_or_timestamp = 1
  25616.     if COLUMNPROPERTY(@temp_id, @column, 'IsIdentity') = 0
  25617.         and not exists (select * from syscolumns where id = @temp_id and name=@column and isnullable=1)
  25618.         and not exists (select * from sysconstraints where id=@temp_id and colid=@temp_colid and status & 5 = 5)
  25619.         and @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'  --not computed column nor timestamp column
  25620.     begin
  25621.         select @invalid_datatype = 1
  25622.     end
  25623. CHECKING_DONE:
  25624. ROLLBACK TRANSACTION fake_move
  25625. COMMIT TRAN
  25626. if @invalid_datatype = 1
  25627.     begin
  25628.         raiserror(21285, 16, -1, @column, @source_object)
  25629.         return (1)
  25630.     end
  25631.     
  25632. if exists (select * from sysobjects where id=@objid and replinfo & @merge_pub_object_bit <>0)
  25633.     select @is_for_merge = 1
  25634. else
  25635.     select @is_for_merge = 0
  25636. select @is_for_tran = 0
  25637. if not exists (select * from sysobjects where name='sysmergepublications') and
  25638.     not exists (select * from sysobjects where name='syspublications')
  25639. begin
  25640.     raiserror(21230, 16, -1)
  25641.     return (1)
  25642. end
  25643.  
  25644. create table #tmp_table (name sysname collate database_default)
  25645.  
  25646. if LOWER(@publication_to_add)='all' or LOWER(@publication_to_add)='[all]'
  25647. begin    
  25648.     select @publication_to_add = '%'
  25649. end
  25650. else 
  25651. begin
  25652. if charindex(',', @publication_to_add)<>0 --publication list
  25653.     begin
  25654.         declare @tmp_publist    nvarchar(4000)
  25655.         declare @total             int
  25656.         declare @invalid_pub    sysname
  25657.         select @invalid_pub = NULL
  25658.             select @tmp_publist = @publication_to_add
  25659.         while @tmp_publist <> ''
  25660.         begin
  25661.             select @tmp_publist = LTRIM(@tmp_publist)
  25662.             select @total=len(@tmp_publist)
  25663.             select @len=charindex(',', @tmp_publist)
  25664.             if @len=0
  25665.                 begin
  25666.                     insert #tmp_table values(@tmp_publist)
  25667.                     select @tmp_publist=''
  25668.                 end
  25669.             else
  25670.                 begin
  25671.                     insert #tmp_table values(substring(@tmp_publist, 1, @len-1))
  25672.                     select @tmp_publist = right(@tmp_publist, @total-@len)
  25673.                 end
  25674.         end
  25675.         if exists (select * from sysobjects where name='sysmergepublications') and 
  25676.             exists (select * from sysobjects where name='syspublications')
  25677.             select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from sysmergepublications) and 
  25678.                                                             name not in (select ('[' + name + ']') from syspublications)
  25679.         else 
  25680.             if exists (select * from sysobjects where name='sysmergepublications') 
  25681.                 select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from sysmergepublications)            
  25682.             else
  25683.                 if exists (select * from sysobjects where name='syspublications')         
  25684.                     select @invalid_pub=name from #tmp_table where name not in (select ('[' + name + ']') from syspublications)                        
  25685.         if @invalid_pub is not NULL and @from_agent=0
  25686.         begin
  25687.             raiserror(21274, 16, -1, @invalid_pub)
  25688.             return (1)        
  25689.         end
  25690.     end
  25691. else 
  25692.     begin --single publication
  25693.         insert #tmp_table values(@publication_to_add)
  25694.         insert #tmp_table values('[' + @publication_to_add + ']')
  25695.     end
  25696.     
  25697. end
  25698.  
  25699.  
  25700.  
  25701. -- if not for TRAN, it has to be a merge publication
  25702. if not exists (select * from sysobjects where name='syspublications')
  25703. begin
  25704.     if not exists (select * from sysmergepublications where name like @publication_to_add 
  25705.                 or (('[' + name + ']') in (select name from #tmp_table)))
  25706.         select @no_publication = 1
  25707.  
  25708.     if not exists (select * from sysmergearticles where objid=@objid and pubid in 
  25709.             (select pubid from sysmergepublications where name like @publication_to_add 
  25710.                     or (('[' + name + ']') in (select name from #tmp_table))))
  25711.         select @no_schema_replication = 1
  25712. end
  25713.  
  25714. -- if not for merge, it has to be a tran publication
  25715. if not exists (select * from sysobjects where name='sysmergepublications')
  25716. begin
  25717.     if not exists (select * from syspublications where name like @publication_to_add 
  25718.                 or (('[' + name + ']') in (select name from #tmp_table))) 
  25719.         select @no_publication = 1
  25720.         
  25721.     if not exists (select * from sysarticles where objid=@objid and pubid in 
  25722.             (select pubid from syspublications where name like @publication_to_add 
  25723.                 or (('[' + name + ']') in (select name from #tmp_table))))
  25724.         select @no_schema_replication =1
  25725. end
  25726.  
  25727. if exists (select * from sysobjects where name='sysmergepublications')
  25728.     and exists (select * from sysobjects where name='syspublications')
  25729. begin
  25730.     if not exists (select * from syspublications where name like @publication_to_add 
  25731.                 or (('[' + name + ']') in (select name from #tmp_table)))
  25732.             and not exists (select * from sysmergepublications where name like @publication_to_add 
  25733.                 or (('[' + name + ']') in (select name from #tmp_table)))
  25734.         select @no_publication = 1
  25735.  
  25736.     if not exists (select * from sysarticles where objid=@objid and pubid in 
  25737.             (select pubid from syspublications where name like @publication_to_add 
  25738.                 or (('[' + name + ']') in (select name from #tmp_table))))
  25739.         and not exists (select * from sysmergearticles where objid=@objid and pubid in 
  25740.             (select pubid from sysmergepublications where name like @publication_to_add 
  25741.                     or (('[' + name + ']') in (select name from #tmp_table))))
  25742.         select @no_schema_replication=1
  25743. end
  25744.  
  25745. if @no_publication=1 and @publication_to_add <> '%' and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
  25746.     begin
  25747.         raiserror(21200, 16, -1, @publication_to_add)
  25748.         return (1)
  25749.     end
  25750.  
  25751. if @no_schema_replication=1 and LOWER(@publication_to_add)<>'none' and LOWER(@publication_to_add)<>'[none]'
  25752.     begin
  25753.         if @publication_to_add = '%'
  25754.             begin
  25755.                 raiserror(21246, 16, -1, @source_object)
  25756.                 return (1)
  25757.             end
  25758.         else
  25759.             begin
  25760.                 raiserror(21245, 16, -1, @source_object, @publication_to_add)
  25761.                 return (1)
  25762.             end
  25763.     end
  25764.  
  25765. select @at_publisher = 0
  25766.  
  25767. if exists (select * from sysobjects where name = 'sysarticles')
  25768. begin
  25769.     if exists (select a.objid from sysarticles a, syspublications p where a.objid=@objid
  25770.                 and p.pubid = a.pubid
  25771.                 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0))
  25772.     begin
  25773.         select @is_for_tran = 1
  25774.     end
  25775. end
  25776.  
  25777. if (@is_for_tran =1 and @force_reinit_subscription = 0)
  25778. begin
  25779.     if (@is_identity_or_timestamp  = 1 )
  25780.     begin
  25781.         raiserror(21380, 16, -1)
  25782.         return (1)
  25783.     end
  25784.     if exists (SELECT P.pubid FROM dbo.syspublications P, dbo.sysarticles A, dbo.syssubscriptions S 
  25785.                     WHERE A.objid = @objid    and A.pubid = P.pubid and A.artid = S.artid
  25786.                         and (P.allow_sync_tran = 1 or P.allow_queued_tran = 1) 
  25787.                         and S.status = 2  -- active
  25788.                         and S.sync_type != 2 -- not 'none'
  25789.                         and S.update_mode != 0 ) -- not 'read only'
  25790.  
  25791.     begin 
  25792.         raiserror(21381, 16, -1, @tablename)
  25793.         return (1)
  25794.     end
  25795. end
  25796.  
  25797. begin TRAN
  25798. save tran sp_repladdcolumn
  25799.     if @is_for_merge=1
  25800.     begin
  25801.         exec sp_replupdateschema @qual_source_object
  25802.          if @@ERROR<>0
  25803.             goto FAILURE
  25804.         
  25805.         exec @retcode = sp_MSunmarkreplinfo @object=@tablename, @owner=@owner
  25806.         if @retcode<>0 or @@ERROR<>0
  25807.             goto FAILURE
  25808.     end
  25809.     if not exists (select * from sysobjects where name='sysmergearticles')
  25810.         select @not_for_merge = 1
  25811.     else
  25812.         if not exists (select * from sysmergearticles where objid=@objid)
  25813.             select @not_for_merge =1
  25814.  
  25815.     if @is_for_tran = 1
  25816.     begin
  25817.         if not exists (select * from syscolumns where name=@column and id =@objid)
  25818.         begin
  25819.             exec @retcode = sp_MSprep_exclusive @qual_source_object
  25820.             if @@ERROR<>0 or @retcode <> 0
  25821.                 goto FAILURE
  25822.             exec @retcode = sp_replincrementlsn @schema_start_lsn OUTPUT
  25823.             if @@ERROR<>0 or @retcode <> 0
  25824.                 goto FAILURE
  25825.             exec @retcode = sp_replpostschema @objid
  25826.             if @@ERROR<>0 or @retcode <> 0
  25827.                 goto FAILURE
  25828.             exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
  25829.                 if @@ERROR<>0
  25830.                     goto FAILURE
  25831.         end
  25832.     end
  25833.     if @not_for_merge = 0
  25834.     begin        
  25835.         if  not exists (select * from syscolumns where name=@column and id =@objid)
  25836.             begin
  25837.                 exec ('alter table '+ @qual_source_object + ' add ' + @qual_column + ' ' + @typetext )
  25838.                 if @@ERROR<>0
  25839.                     goto FAILURE
  25840.             end
  25841.  
  25842.         /*
  25843.         ** whether the column is added to this publication, the articles whose underlying table contains
  25844.         ** a new column will be regareded as vertically partitioned.
  25845.         */ 
  25846.         update sysmergearticles set vertical_partition=1 where objid=@objid
  25847.         if @@ERROR<>0
  25848.             goto FAILURE
  25849.  
  25850.         /*
  25851.         ** Heterogenious subscriber are not to receive computed column or timestamp columns
  25852.         */
  25853.         declare #nosnapshot CURSOR LOCAL FAST_FORWARD for
  25854.             select p.name, a.name, a.pubid from sysmergepublications p, sysmergearticles a 
  25855.                     where p.pubid=a.pubid and a.objid=@objid and p.snapshot_ready=0 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
  25856.                             and (p.sync_mode=0 or @pass_to_heterogenious=1)                    
  25857.             open #nosnapshot
  25858.             fetch #nosnapshot into @pubname, @artname, @pubid
  25859.                 while (@@fetch_status<>-1)
  25860.                 begin
  25861.                     exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'add', 'true'
  25862.                     if @retcode <>0 or @@ERROR<>0
  25863.                         goto ERROR_EXIT
  25864.                     fetch #nosnapshot into @pubname, @artname, @pubid                    
  25865.                 end
  25866.         CLOSE #nosnapshot
  25867.         DEALLOCATE #nosnapshot
  25868.                 
  25869.         
  25870.         /*
  25871.         ** Handle those cases where snapshot is already ran and new schema change needs to be added
  25872.         ** ; Heterogenious subscriber are not to receive computed column or timestamp columns
  25873.         */
  25874.         declare #addcolumn CURSOR LOCAL FAST_FORWARD fast_forward for 
  25875.                 select pubid, name, sync_objid, artid, conflict_table, ins_conflict_proc, destination_owner
  25876.                     from sysmergearticles where objid=@objid and pubid
  25877.                         in (select pubid from sysmergepublications where snapshot_ready>0 
  25878.                             and (sync_mode=0 or @pass_to_heterogenious=1))
  25879.         open #addcolumn
  25880.         fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @conflict_table, @ins_conflict_proc, @dest_owner
  25881.         while (@@fetch_status <> -1)
  25882.         BEGIN
  25883.                 if @dest_owner is not NULL
  25884.                     select @dest_object = QUOTENAME(@dest_owner) + '.' + QUOTENAME(@tablename)
  25885.                 else
  25886.                     select @dest_object = QUOTENAME(@tablename)
  25887.  
  25888.                 select @pubname=name, @publisher=publisher, @publisher_db=publisher_db
  25889.                     from sysmergepublications where pubid=@pubid
  25890.  
  25891.                 if @conflict_table is not NULL 
  25892.                 begin
  25893.                     select @con_id = object_id(@conflict_table)
  25894.                     if @con_id is NULL
  25895.                         begin
  25896.                             raiserror(21286, 16, -1, @conflict_table)
  25897.                             GOTO INNER_FAIL
  25898.                         end
  25899.                     if not exists (select name from syscolumns where name=@column and id=@con_id) and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
  25900.                     begin
  25901.                         select @typename = type_name(xtype), @len = length, @prec = COLUMNPROPERTY(id, name, 'precision'),
  25902.                                 @scale = scale, @iscomputed=iscomputed, @xtype=xtype    
  25903.                             from syscolumns where name=@column and id=@objid
  25904.                         --we want to column property of 'computed' or 'timestamp' of the newly added column
  25905.                         if @iscomputed <> 1 and type_name(@xtype) <> 'timestamp'
  25906.                         begin
  25907.                             if @typename='nvarchar' or @typename='nchar' -- a unit of nchar takes 2 bytes 
  25908.                                 select @len = @len/2
  25909.                             exec @retcode = dbo.sp_MSmaptype @typename out, @len, @prec, @scale
  25910.                             if @@error<>0 OR @retcode <>0 
  25911.                                 GOTO INNER_FAIL
  25912.                             --doing so instead of using @typetext as we once did is that we do not want any constraint or identity properties 
  25913.                             --defined on conflict tables. Also it is safe to make the column NULLable in conflict tables.
  25914.                             select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typename + ' NULL '
  25915.                         end
  25916.                         else
  25917.                         --continue to use typetext when adding computed/timestamp column to the conflict tables.
  25918.                         begin
  25919.                             select @command = 'alter table ' + QUOTENAME(@conflict_table) + ' add ' + @qual_column + ' ' + @typetext                        
  25920.                         end
  25921.                         exec (@command)
  25922.                         if @@ERROR<>0
  25923.                         goto INNER_FAIL
  25924.  
  25925.                     end
  25926.                 end
  25927.             
  25928.             /*
  25929.             ** Force the re-generation of conflict insert table cause the schema is changed for sure
  25930.             */
  25931.                 if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL and (@pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0)
  25932.                 begin
  25933.                     exec ('drop procedure ' + @ins_conflict_proc)
  25934.                     if @@ERROR<>0
  25935.                         goto INNER_FAIL
  25936.                     update sysmergearticles set ins_conflict_proc=NULL where pubid=@pubid and artid=@artid
  25937.                     if @@ERROR<>0
  25938.                         goto INNER_FAIL
  25939.                 end
  25940.  
  25941.             /*
  25942.             ** Force the regeneration of publication view for all publications that publish the current table.
  25943.             */
  25944.                 update sysmergearticles set vertical_partition=1 where artid=@artid and pubid=@pubid
  25945.                 if @@ERROR<>0
  25946.                     goto INNER_FAIL
  25947.             
  25948.                 select @at_publisher=0
  25949.                 if @publisher=@@SERVERNAME and @publisher_db=db_name()
  25950.                 begin
  25951.                     select @at_publisher=1
  25952.                     if @pubname like @publication_to_add or charindex('[' + @pubname + ']', @publication_to_add)>0
  25953.                     begin
  25954.                         select @schematext = 'exec sp_repladdcolumn ''' + @dest_object + ''',''' + @column + ''','+  QUOTENAME(@typetext) + ', ''' + @publication_to_add + ''', 1'  
  25955.                         select @schemaversion = schemaversion from sysmergeschemachange
  25956.                         if (@schemaversion is NULL)
  25957.                             set @schemaversion = 1
  25958.                         else
  25959.                             select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange        
  25960.                         set @schemaguid = newid()
  25961.                         set @schematype = 11 /* alter table */
  25962.                         exec @retcode = sp_mergearticlecolumn @pubname, @artname, @column, 'add','true'
  25963.                         if @retcode<>0 or @@ERROR<>0
  25964.                             goto INNER_FAIL -- need to deallocate cursor for this loop.
  25965.                         exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext
  25966.                         if @@ERROR<>0 or @retcode<>0 
  25967.                             goto INNER_FAIL
  25968.                             
  25969.                         --insert a schema change for Jet specifically subscribers    
  25970.                         select @schematext = 'alter table ' +  @dest_object + ' add ' + @column + ' ' + @typetext
  25971.                         select @schemaversion = @schemaversion + 1
  25972.                         set @schematype = 13 -- for Jet use only
  25973.                         set @schemaguid = newid()
  25974.                         exec @retcode=sp_MSinsertschemachange @pubid, @artid, @schemaversion, @schemaguid, @schematype, @schematext                        
  25975.                         if @@ERROR<>0 or @retcode<>0 
  25976.                             goto INNER_FAIL
  25977.                     end
  25978.                 end
  25979.     
  25980.                 if @at_publisher=1
  25981.                 begin
  25982.                     exec @retcode = sp_MSpublicationview @pubname, 1
  25983.                     if @retcode<>0 or @@ERROR<>0
  25984.                         goto INNER_FAIL
  25985.                 end
  25986.  
  25987.                 select @columns_in_partition=count(*) from syscolumns where id = @sync_objid
  25988.                 if @columns_in_partition>246
  25989.                 begin
  25990.                     raiserror('Failed to add column ''%s'' to table ''%s'' because there are too many columns in the partition', 16, -1,@column, @source_object)
  25991.                     goto INNER_FAIL
  25992.                 end
  25993.             
  25994.                 exec @retcode = sp_MSdroparticletriggers @qual_source_object
  25995.                 if @retcode<>0 or @@ERROR<>0
  25996.                     goto INNER_FAIL
  25997.                 exec @retcode = sp_MSaddmergetriggers @qual_source_object
  25998.                 if @retcode<>0 or @@ERROR<>0
  25999.                     goto INNER_FAIL
  26000.  
  26001.                 /*
  26002.                 ** Force the regeneration of merge procs for all publications that publish the current table
  26003.                 */
  26004.                     
  26005.                 exec @retcode = sp_MSsetartprocs @publication=@pubname, @article=@artname, @force_flag=1
  26006.                 if @retcode<>0 or @@ERROR<>0
  26007.                     goto INNER_FAIL
  26008.         /*
  26009.         ** passing in one more parameter to sp_MSgetconflictinsertproc such that there is 
  26010.         ** no select statement at the end of that SP as needed else where. The default is 1.
  26011.         */
  26012.                 exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0
  26013.                 if @retcode<>0 or @@ERROR<>0
  26014.                     goto INNER_FAIL
  26015.  
  26016.                 fetch #addcolumn into @pubid, @artname, @sync_objid, @artid, @conflict_table, @ins_conflict_proc, @dest_owner
  26017.         END
  26018.         close #addcolumn
  26019.         deallocate #addcolumn
  26020.     
  26021.         declare @column_tracking int
  26022.         select @column_tracking=column_tracking, @nickname=nickname from sysmergearticles where objid=@objid
  26023.         if @column_tracking = 1
  26024.         begin
  26025.             --make sure there is no colv overflow, which was not caught by 246 column restriction because
  26026.             --users keep adding/dropping column, which causes no increase in number of coumns but consume
  26027.             --colv slot cause we never release the slot when a column is dropped
  26028.             if exists (select * from MSmerge_contents where tablenick=@nickname and len(colv1)>2040)
  26029.             begin                
  26030.                 raiserror(21418, 16, -1,@column, @source_object)
  26031.                 goto INNER_FAIL
  26032.             end
  26033.             --apend an lineage slot for the new column. 
  26034.             update MSmerge_contents set 
  26035.                 colv1=substring(colv1, 1, (datalength(colv1)-1)) + substring(colv1, 1, 4) + 0x01000000FF
  26036.                     where tablenick=@nickname
  26037.             if @@ERROR<>0
  26038.                 goto FAILURE
  26039.         end
  26040.     end
  26041.  
  26042.     if @is_for_tran = 1
  26043.     begin 
  26044.         declare #trancolumn CURSOR LOCAL FAST_FORWARD for 
  26045.             select a.artid, p.name from sysarticles a, syspublications p where a.objid=@objid
  26046.                 and p.pubid = a.pubid
  26047.                 and (p.name like @publication_to_add or charindex('[' + p.name + ']', @publication_to_add)>0)
  26048.         open #trancolumn
  26049.         fetch #trancolumn into @tran_artid, @pubname
  26050.         while (@@fetch_status <> -1)
  26051.         BEGIN
  26052.             select @artname = name, @tran_pubid = pubid, @owner = dest_owner, @tablename = dest_table from sysarticles where artid=@tran_artid
  26053.             exec @retcode = sp_articlecolumn @publication = @pubname, @article = @artname, @column = @column, 
  26054.                              @operation = 'add', @change_active = 2
  26055.                             ,@force_invalidate_snapshot = 1
  26056.                             ,@force_reinit_subscription = 1
  26057.             if @retcode <>0 or @@ERROR<>0
  26058.                 goto DROPTRAN
  26059.             if(@force_reinit_subscription = 0)    
  26060.             begin
  26061.                 if(@owner is not NULL) and (len(@owner) > 0)
  26062.                     select @qual_dest_object = QUOTENAME(@owner) + N'.' 
  26063.                 else 
  26064.                     select @qual_dest_object = N'' 
  26065.                 if(@tablename is not null) and (len(@tablename) > 0)
  26066.                     select @qual_dest_object = @qual_dest_object + QUOTENAME(@tablename)
  26067.                 else 
  26068.                     select @qual_dest_object = @qual_source_object
  26069.                 exec @retcode = sp_MSrepl_schema @pubname = @pubname 
  26070.                             ,@artid = @tran_artid
  26071.                             ,@qual_source_object = @qual_dest_object
  26072.                             ,@column = @column
  26073.                             ,@operation = 0 -- 0 is add, 1 is delete
  26074.                             ,@typetext = @typetext
  26075.                             ,@schema_change_script = @schema_change_script
  26076.                 if @retcode <>0 or @@ERROR<>0
  26077.                     goto DROPTRAN
  26078.             end
  26079.             exec @retcode = dbo.sp_MSreinit_article 
  26080.                             @publication = @pubname
  26081.                             ,@article = @artname
  26082.                             ,@need_new_snapshot = @force_invalidate_snapshot
  26083.                             ,@need_reinit_subscription = @force_reinit_subscription 
  26084.                             ,@force_invalidate_snapshot = @force_invalidate_snapshot
  26085.                             ,@force_reinit_subscription = @force_reinit_subscription
  26086.             if @retcode <>0 or @@ERROR<>0
  26087.                 goto DROPTRAN
  26088.             fetch #trancolumn into @tran_artid, @pubname            
  26089.         END
  26090.         close #trancolumn
  26091.         deallocate #trancolumn
  26092.          exec @retcode = sp_replincrementlsn @schema_end_lsn OUTPUT
  26093.          if @@ERROR<>0 or @retcode <> 0
  26094.              goto FAILURE
  26095.          if (@schema_start_lsn is not null) and (@schema_end_lsn is not null)
  26096.          begin
  26097.              insert systranschemas (tabid, startlsn, endlsn) values (@objid, @schema_start_lsn, @schema_end_lsn)
  26098.              if @@ERROR<>0
  26099.                  goto FAILURE
  26100.              exec @retcode = sp_replflush @objid, @schema_start_lsn, @schema_end_lsn
  26101.              if @@ERROR<>0 or @retcode <> 0
  26102.                  goto FAILURE
  26103.          end
  26104.          else
  26105.              goto FAILURE
  26106.     end
  26107.     
  26108.     /* Get back to its original replication state */
  26109.     if @is_for_merge=1
  26110.     begin
  26111.         exec @retcode = sp_MSmarkreplinfo @tablename, @owner
  26112.         if @retcode<>0 or @@ERROR<>0
  26113.             goto FAILURE
  26114.         update syscolumns set colstat = colstat | @merge_pub_markcolumn_bit where id=@objid and name= @column
  26115.         if @@ERROR<>0
  26116.             goto FAILURE
  26117.     end
  26118.  
  26119. COMMIT TRAN
  26120. return (0)
  26121.  
  26122. INNER_FAIL:
  26123. CLOSE #addcolumn
  26124. DEALLOCATE #addcolumn
  26125. GOTO FAILURE
  26126.  
  26127. ERROR_EXIT:
  26128. CLOSE #nosnapshot
  26129. DEALLOCATE #nosnapshot
  26130. GOTO FAILURE
  26131.  
  26132. DROPTRAN:
  26133. CLOSE #trancolumn
  26134. DEALLOCATE #trancolumn
  26135.  
  26136. FAILURE:
  26137.     rollback tran sp_repladdcolumn
  26138.     commit tran
  26139.     raiserror(21285, 16, -1, @column, @source_object)
  26140.     return (1)    
  26141. go
  26142.  
  26143. exec dbo.sp_MS_marksystemobject sp_repladdcolumn 
  26144. go
  26145.  
  26146. EXEC dbo.sp_MS_marksystemobject sp_MSget_jobstate
  26147. GO
  26148.  
  26149. exec dbo.sp_MS_marksystemobject sp_MSunc_to_drive
  26150. go
  26151.  
  26152. exec dbo.sp_MS_marksystemobject sp_MSrepl_isdbowner
  26153. go
  26154.  
  26155. grant execute on dbo.sp_MSget_qualified_name to public
  26156. go
  26157.  
  26158. dump tran master with no_log
  26159. go
  26160.  
  26161. raiserror('Creating procedure sp_MSagent_access_check',0,1)
  26162. go
  26163. CREATE PROCEDURE sp_MSagent_access_check (
  26164.     @job_id         VARBINARY(16),
  26165.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  26166. ) AS
  26167.  
  26168.     DECLARE @retcode int
  26169.     DECLARE @count   int
  26170.  
  26171.     IF @agent_type IS NOT NULL
  26172.     BEGIN
  26173.         IF LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) NOT IN (N'distribution', N'merge')
  26174.         BEGIN
  26175.             RAISERROR(21170, 16, -1)
  26176.             RETURN (1)
  26177.         END
  26178.     END
  26179.  
  26180.     SELECT @retcode = 0
  26181.     -- Create a list of owners of the subscriptions depending on the given 
  26182.     -- agent 
  26183.     CREATE TABLE #sub_owner_list (owner_name sysname collate database_default)
  26184.  
  26185.     -- Try querying the Transactional subscriptions for the owner 
  26186.     IF @agent_type IS NULL OR LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) = N'distribution'
  26187.     BEGIN
  26188.  
  26189.         IF EXISTS (SELECT * 
  26190.                      FROM sysobjects 
  26191.                     WHERE type in ('U', 'S') AND name = N'syssubscriptions')
  26192.         BEGIN
  26193.             INSERT INTO #sub_owner_list 
  26194.             SELECT DISTINCT login_name 
  26195.               FROM dbo.syssubscriptions 
  26196.              WHERE distribution_jobid = @job_id 
  26197.         END
  26198.  
  26199.         IF NOT EXISTS (SELECT * FROM #sub_owner_list) AND 
  26200.            @agent_type IS NOT NULL
  26201.         BEGIN
  26202.             RAISERROR(21167, 16, -1, 'Distribution')
  26203.             SELECT @retcode = 1
  26204.             GOTO FAILURE
  26205.         END 
  26206.     END
  26207.  
  26208.     IF (@agent_type IS NULL AND NOT EXISTS (SELECT * FROM #sub_owner_list)) OR
  26209.        LOWER(@agent_type collate SQL_Latin1_General_CP1_CS_AS) = N'merge' 
  26210.     BEGIN
  26211.         
  26212.         SELECT @count = COUNT(*)
  26213.           FROM sysobjects
  26214.          WHERE name IN (N'sysmergesubscriptions', N'MSmerge_replinfo')
  26215.         
  26216.         IF @count = 2        
  26217.         BEGIN
  26218.             INSERT INTO #sub_owner_list 
  26219.             SELECT DISTINCT sms.login_name 
  26220.               FROM dbo.MSmerge_replinfo mr
  26221.         INNER JOIN dbo.sysmergesubscriptions sms
  26222.                 ON mr.repid = sms.subid
  26223.              WHERE mr.merge_jobid = @job_id
  26224.         END
  26225.  
  26226.         IF NOT EXISTS (SELECT * FROM #sub_owner_list) AND 
  26227.            @agent_type IS NOT NULL
  26228.         BEGIN
  26229.             RAISERROR(21167, 16, -1, 'Merge')
  26230.             SELECT @retcode = 1
  26231.             GOTO FAILURE
  26232.         END 
  26233.     END
  26234.  
  26235.     IF NOT EXISTS (SELECT * FROM #sub_owner_list) 
  26236.     BEGIN
  26237.         RAISERROR(21134, 16, -1)
  26238.         SELECT @retcode = 1
  26239.         GOTO FAILURE
  26240.     END
  26241.  
  26242.     IF suser_sname(suser_sid()) NOT IN (SELECT owner_name FROM #sub_owner_list) AND
  26243.        is_srvrolemember('sysadmin') <> 1 AND
  26244.        is_member('db_owner') <> 1
  26245.     BEGIN
  26246.  
  26247.         RAISERROR(21168, 16, -1)
  26248.         SELECT @retcode = 1
  26249.         GOTO FAILURE
  26250.     END
  26251.  
  26252. FAILURE:
  26253.  
  26254.     DROP TABLE #sub_owner_list
  26255.     RETURN @retcode
  26256.  
  26257. GO
  26258.  
  26259. EXEC dbo.sp_MS_marksystemobject sp_MSagent_access_check
  26260. GO
  26261.  
  26262. raiserror('Creating procedure sp_enableagentoffload',0,1)
  26263. go
  26264. CREATE PROCEDURE sp_enableagentoffload (
  26265.     @job_id         VARBINARY(16),
  26266.     @offloadserver  sysname = NULL,
  26267.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  26268.     ) AS
  26269.     SET NOCOUNT ON
  26270.     DECLARE @retcode        INT
  26271.     DECLARE @distributor    sysname
  26272.     DECLARE @distributiondb sysname
  26273.     DECLARE @distproc       NVARCHAR(300)
  26274.  
  26275.     SELECT @retcode = 0
  26276.     SELECT @distributor    = NULL
  26277.     SELECT @distributiondb = NULL
  26278.  
  26279.     EXEC @retcode = sp_MSreplcheckoffloadserver @offloadserver
  26280.     IF @retcode<>0 OR @@error<>0
  26281.         RETURN (1)
  26282.  
  26283.     EXEC @retcode = sp_MSagent_access_check @job_id = @job_id, 
  26284.                                             @agent_type = @agent_type
  26285.  
  26286.     IF @retcode <> 0
  26287.         RETURN @retcode        
  26288.  
  26289.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  26290.                                            @distribdb = @distributiondb OUTPUT
  26291.     IF @retcode <> 0
  26292.         RETURN @retcode
  26293.  
  26294.     SELECT @distributor = RTRIM(@distributor)
  26295.  
  26296.     IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  26297.     BEGIN 
  26298.         SELECT @distproc = @distributor + '.' + @distributiondb + 
  26299.                            '.dbo.sp_MSenableagentoffload'
  26300.     END
  26301.     ELSE
  26302.     BEGIN
  26303.         SELECT @distproc = @distributiondb + '.dbo.sp_MSenableagentoffload'
  26304.     END
  26305.  
  26306.     EXECUTE @retcode = @distproc 
  26307.                 @job_id = @job_id,
  26308.                 @offloadserver = @offloadserver
  26309.  
  26310.     RETURN @retcode
  26311. GO
  26312. EXEC dbo.sp_MS_marksystemobject sp_enableagentoffload
  26313. GO
  26314.  
  26315. print ''
  26316. print 'Creating procedure sp_disableagentoffload'
  26317. go
  26318. CREATE PROCEDURE sp_disableagentoffload (
  26319.     @job_id         VARBINARY(16),
  26320.     @offloadserver  sysname = NULL,
  26321.     @agent_type     sysname = NULL -- 'distribution' or 'merge', case insensitive
  26322. ) AS
  26323.     SET NOCOUNT ON
  26324.     DECLARE @retcode        INT
  26325.     DECLARE @distributor    sysname
  26326.     DECLARE @distributiondb sysname
  26327.     DECLARE @distproc       NVARCHAR(300)
  26328.  
  26329.     SELECT @retcode = 0
  26330.     SELECT @distributor    = NULL
  26331.     SELECT @distributiondb = NULL
  26332.  
  26333.     EXEC @retcode = sp_MSagent_access_check @job_id = @job_id, 
  26334.                                             @agent_type = @agent_type
  26335.  
  26336.     IF @retcode <> 0
  26337.         RETURN @retcode        
  26338.     
  26339.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  26340.                                            @distribdb = @distributiondb OUTPUT
  26341.  
  26342.     IF @retcode <> 0
  26343.         RETURN @retcode
  26344.  
  26345.     SELECT @distributor = RTRIM(@distributor)
  26346.  
  26347.     IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  26348.     BEGIN 
  26349.         SELECT @distproc = @distributor + '.' + @distributiondb + 
  26350.                            '.dbo.sp_MSdisableagentoffload'
  26351.     END
  26352.     ELSE
  26353.     BEGIN
  26354.         SELECT @distproc = @distributiondb + '.dbo.sp_MSdisableagentoffload'
  26355.     END
  26356.  
  26357.     EXECUTE @retcode = @distproc 
  26358.                 @job_id = @job_id,
  26359.                 @offloadserver = @offloadserver
  26360.  
  26361.     RETURN @retcode
  26362. GO
  26363. EXEC dbo.sp_MS_marksystemobject sp_disableagentoffload
  26364. GO
  26365.  
  26366. print ''
  26367. print 'Creating procedure sp_getagentoffloadinfo'
  26368. go
  26369. CREATE PROCEDURE sp_getagentoffloadinfo (
  26370.     @job_id         VARBINARY(16)
  26371. ) AS
  26372.     SET NOCOUNT ON
  26373.     DECLARE @retcode        INT
  26374.     DECLARE @distributor    sysname
  26375.     DECLARE @distributiondb sysname
  26376.     DECLARE @distproc       NVARCHAR(300)
  26377.  
  26378.     SELECT @retcode = 0
  26379.     SELECT @distributor    = NULL
  26380.     SELECT @distributiondb = NULL
  26381.  
  26382.     EXEC @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  26383.                                            @distribdb = @distributiondb OUTPUT
  26384.  
  26385.     IF @retcode <> 0
  26386.         RETURN @retcode
  26387.  
  26388.     SELECT @distributor = RTRIM(@distributor)
  26389.  
  26390.     IF LOWER(@@SERVERNAME) <> LOWER(@distributor)
  26391.     BEGIN 
  26392.         SELECT @distproc = @distributor + '.' + @distributiondb + 
  26393.                            '.dbo.sp_MSgetagentoffloadinfo'
  26394.     END
  26395.     ELSE
  26396.     BEGIN
  26397.         SELECT @distproc = @distributiondb + '.dbo.sp_MSgetagentoffloadinfo'
  26398.     END
  26399.     EXECUTE @retcode = @distproc 
  26400.                 @job_id = @job_id
  26401.  
  26402.     RETURN @retcode
  26403. GO
  26404. EXEC dbo.sp_MS_marksystemobject sp_getagentoffloadinfo
  26405. GO
  26406.  
  26407. print ''
  26408. print 'Creating procedure sp_copysubscription'
  26409. go
  26410. CREATE PROCEDURE sp_copysubscription (
  26411. @filename nvarchar(260),
  26412. @temp_dir nvarchar(260) = NULL,
  26413. -- Directory contains temp files. If not specified, SQL
  26414. -- server default data directory will be used.
  26415. @overwrite_existing_file bit = 0
  26416. )
  26417. AS
  26418.  
  26419.     SET NOCOUNT ON
  26420.  
  26421.     /*
  26422.     ** Declarations.
  26423.     */
  26424.     declare @cmd nvarchar(4000)
  26425.     declare @retcode int
  26426.     declare @data_path nvarchar(260)
  26427.     declare @subscriber_srvid     int
  26428.     declare @subscriber_db        sysname
  26429.     declare @backup_path nvarchar(260)
  26430.     declare @temp_data_path nvarchar(260)
  26431.     declare @temp_log_path nvarchar(260)
  26432.     declare @retention            int
  26433.     declare @retention_date       datetime
  26434.     declare @pubid                 uniqueidentifier
  26435.  
  26436.  
  26437.     /*
  26438.     * Initializations
  26439.     */
  26440.     select @retcode = 0
  26441.     select @subscriber_srvid = 0
  26442.     select @subscriber_db = db_name()
  26443.  
  26444.     -- We only support single file attach. Check to make sure
  26445.     -- there are only 2 files, one data file and one log file
  26446.     if (select count(*) from sysfiles) > 2
  26447.     begin
  26448.         raiserror(21212,16, -1)
  26449.         return 1
  26450.     end
  26451.  
  26452.     /* Make sure all tran sub allows attach */
  26453.     declare @publication                 sysname
  26454.     declare @publisher                    sysname
  26455.     declare @tran_found                    bit
  26456.     declare @merge_found                bit
  26457.     select @tran_found = 0
  26458.     select @merge_found = 0
  26459.  
  26460.     /* 
  26461.     ** Make sure all merge subscriptions in the current database 
  26462.     ** have allow_subscription_copy set to TRUE
  26463.     ** and there are no push subscriptions. 
  26464.     */
  26465.     if exists (select * from sysobjects where name = 'MSsubscription_agents')
  26466.     begin
  26467.         set @publisher = NULL
  26468.         -- Not using @publication because share agent case.
  26469.         select top 1 @publisher = publisher from MSsubscription_agents where
  26470.             allow_subscription_copy = 0
  26471.         IF @publisher is not null
  26472.         BEGIN
  26473.             RAISERROR(21236, 16, -1, @publisher)
  26474.             RETURN (1)
  26475.         END
  26476.  
  26477.         set @publisher = null
  26478.         select top 1 @publisher = publisher from MSreplication_subscriptions where
  26479.             subscription_type = 0
  26480.         IF @publisher is not null
  26481.         BEGIN
  26482.             RAISERROR(21237, 16, -1, @publisher)            
  26483.             RETURN (1)
  26484.         END
  26485.         if exists (select * from MSsubscription_agents)
  26486.             select @tran_found = 1
  26487.     end            
  26488.  
  26489.     /* 
  26490.     ** Make sure all merge subscriptions in the current database 
  26491.     ** have allow_subscription_copy set to TRUE
  26492.     ** and there are no push subscriptions. 
  26493.     */
  26494.     if exists (select * from sysobjects where name = 'sysmergepublications')
  26495.         begin
  26496.             set @publication = NULL
  26497.             select top 1 @publication = name from sysmergepublications where
  26498.                 allow_subscription_copy = 0
  26499.             IF @publication is not null
  26500.                 BEGIN
  26501.                     RAISERROR (21204, 16, -1, @publication)    
  26502.                     RETURN (1)
  26503.                 END
  26504.  
  26505.             set @publication = null
  26506.             select top 1 @publication = p.name from sysmergepublications p, 
  26507.                 sysmergesubscriptions s where
  26508.                 p.pubid = s.pubid and
  26509.                 s.subid <> s.pubid and 
  26510.                 db_name = db_name() collate database_default and 
  26511.                 subscriber_server = convert(nvarchar(4000), SERVERPROPERTY('ServerName')) collate database_default  and
  26512.                 s.subscription_type = 0
  26513.             IF @publication is not null
  26514.             BEGIN
  26515.                 RAISERROR(21238, 16, -1, @publication)            
  26516.                 RETURN (1)
  26517.             END
  26518.  
  26519.             -- Does db contains subscriptions?
  26520.             if exists (select * from sysmergesubscriptions where subid <> pubid and 
  26521.                 db_name = db_name() collate database_default and 
  26522.                 subscriber_server = convert(nvarchar(4000), SERVERPROPERTY('ServerName')) collate database_default)
  26523.                 select @merge_found = 1
  26524.  
  26525.             /* Retention check : Make sure that the subscription copy is not too old */
  26526.             declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT p.name, p.pubid, p.retention from sysmergepublications p, sysmergesubscriptions s 
  26527.                 where s.subid=p.pubid and s.pubid=p.pubid for read only
  26528.             open PC
  26529.             fetch PC into @publication, @pubid, @retention 
  26530.             
  26531.             WHILE (@@fetch_status <> -1)
  26532.                 BEGIN
  26533.                     /* Compute the retention period cutoff dates per publication */
  26534.                     select @retention_date = dateadd(day, -@retention, getdate())
  26535.                        if @retention is not NULL and @retention > 0
  26536.                     begin
  26537.                         if not exists (select coldate from sysmergearticles , MSmerge_genhistory 
  26538.                                             where    nickname = art_nick 
  26539.                                                     and coldate > @retention_date 
  26540.                                                     and sysmergearticles.pubid = @pubid)
  26541.                             begin
  26542.                                 RAISERROR (21306, 16, -1, @publication)
  26543.                                 return (1)
  26544.                             end                                
  26545.                     end
  26546.                     fetch PC into @publication, @pubid, @retention
  26547.                 END
  26548.  
  26549.         end            
  26550.  
  26551.     if @tran_found = 0 and @merge_found = 0
  26552.     begin
  26553.         raiserror(21239, 16 , -1)
  26554.         return (1)
  26555.     end
  26556.     
  26557.     -- Security check
  26558.     -- Only DBO or sysadmin can do this
  26559.     -- The user also must have create db permissions.
  26560.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  26561.     IF @retcode <> 0 or @@error <> 0
  26562.         return 1
  26563.  
  26564.     if @overwrite_existing_file is null
  26565.         set @overwrite_existing_file = 0
  26566.  
  26567.     -- Check to see if the file already exists
  26568.     declare @exists bit
  26569.  
  26570.     if @overwrite_existing_file = 0
  26571.     begin
  26572.         exec @retcode = dbo.sp_MSget_file_existence @filename, @exists output
  26573.         if @@error <> 0 or @retcode <> 0
  26574.             return 1
  26575.         if @exists <> 0 
  26576.         begin
  26577.             raiserror(21214, 16, -1, @filename)
  26578.             return 1
  26579.         end
  26580.     end
  26581.  
  26582.     -- Check to see if have write permissions to the file location.
  26583.     -- Try create the file
  26584.     -- Echo text can be anything.
  26585.     select @cmd = 'echo Subscription copy failed. > "' + @filename + '"'
  26586.     exec @retcode = master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  26587.     if @@error <> 0 or @retcode <> 0
  26588.     begin
  26589.         raiserror(21247, 16, -1, @filename)
  26590.         select @retcode = 1
  26591.         goto Cleanup
  26592.     end    
  26593.     -- File should be created.
  26594.     exec @retcode = dbo.sp_MSget_file_existence @filename, @exists output
  26595.     if @@error <> 0 or @retcode <> 0
  26596.     begin
  26597.         select @retcode = 1
  26598.         goto Cleanup
  26599.     end
  26600.     if @exists = 0
  26601.     begin
  26602.         raiserror(21247,16, -1, @filename)
  26603.         select @retcode = 1
  26604.         goto Cleanup
  26605.     end
  26606.  
  26607.     /*
  26608.     ** Get the MSSQL DATA path. Note that users can have a SQLDataRoot directory different from SQLPath
  26609.     */
  26610.     if @temp_dir is null
  26611.     begin
  26612.         exec @retcode = master.dbo.sp_MSget_setup_paths
  26613.             @data_path = @temp_dir output
  26614.         IF @retcode <> 0 or @@error <> 0
  26615.             return 1
  26616.         select @temp_dir = @temp_dir + '\DATA\'
  26617.     end
  26618.     else
  26619.     begin
  26620.         -- Check to make sure working dir is valid.
  26621.         exec @retcode = dbo.sp_MSget_file_existence @temp_dir, @exists output
  26622.         if @@error <> 0 or @retcode <> 0
  26623.         begin
  26624.             select @retcode = 1
  26625.             goto Cleanup
  26626.         end
  26627.         if @exists = 0
  26628.         begin
  26629.             raiserror (21037, 16, -1, @temp_dir)        
  26630.             select @retcode = 1
  26631.             goto Cleanup
  26632.         end
  26633.         if substring(@temp_dir, len(@temp_dir), 1) <> '\'
  26634.             select @temp_dir = @temp_dir + '\'
  26635.     end
  26636.  
  26637.     -- Get temp db name
  26638.     -- Use a guid to avoid name colision.
  26639.     declare @dbname sysname
  26640.     select @dbname = db_name()
  26641.     declare @temp_db_name sysname
  26642.     declare @guid_name nvarchar(36)
  26643.     select @guid_name =  convert (nvarchar(36), newid())
  26644.  
  26645.     select @temp_db_name = 'repl_sub_restore_' + @guid_name
  26646.  
  26647.     select @backup_path = @temp_dir + @temp_db_name + '.bak'
  26648.  
  26649.     -- Create table used to signal attach or restored process to do different things
  26650.     if not exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  26651.     begin 
  26652.         CREATE TABLE dbo.MSreplication_restore_stage
  26653.         (
  26654.         stage_id int -- not used for now
  26655.         )
  26656.         IF @@ERROR <> 0
  26657.             return 1
  26658.     end
  26659.     
  26660.     -- First backup the database to the file given
  26661.     -- Overwrite the existing file with INIT option.
  26662.     BACKUP DATABASE @dbname TO DISK = @backup_path WITH INIT
  26663.     if @@error<> 0
  26664.     begin
  26665.         select @retcode = 1
  26666.         goto Cleanup
  26667.     end
  26668.  
  26669.  
  26670.     -- Restore it to a temporary working database
  26671.     -- Get phy data and log file name for the temp db
  26672.     select @temp_data_path = @temp_dir + @temp_db_name + '.mdf'
  26673.     select @temp_log_path = @temp_dir + @temp_db_name + '.ldf'
  26674.  
  26675.     -- Get the command
  26676.     select @cmd = 'restore database ' + quotename(@temp_db_name) + ' from disk = ' 
  26677.         + quotename(@backup_path,'''') + ' with replace, move '
  26678.  
  26679.     -- Get the logical file name for data file.
  26680.     select @cmd = @cmd + quotename(rtrim(name),'''') from sysfiles where
  26681.         (status & 0x40) = 0
  26682.  
  26683.     -- Use passed in filename as phy data file name for the temp db
  26684.  
  26685.     -- Use the passed in file as phy data file for the temp db
  26686.     select @cmd = @cmd + ' to ' + quotename(@temp_data_path,'''') + ', move '
  26687.  
  26688.     -- Get the logical file name for the log file
  26689.     select @cmd = @cmd + quotename(rtrim(name),'''') from sysfiles where
  26690.         (status & 0x40) <> 0
  26691.  
  26692.     -- Use the passed in file as phy file for the temp db
  26693.     select @cmd = @cmd + ' to ' + quotename(@temp_log_path,'''') + ' '
  26694.     exec (@cmd)
  26695.     if @@error<> 0
  26696.     begin
  26697.         select @retcode = 1
  26698.         goto Cleanup
  26699.     end
  26700.  
  26701.     -- Once we successfully restored, we delete to back up file to save disk space.
  26702.     if @backup_path is not null
  26703.     begin
  26704.         select @cmd = 'del ' + quotename(@backup_path,'"') 
  26705.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26706.         set @backup_path = null
  26707.     end
  26708.  
  26709.     -- Prepare the database for detach. 2 things will be done
  26710.     -- 1. Set a flag to indicate that this is a prepare sub db for detach
  26711.     -- 2. For merge, create table to store sysservers info for later fixing up after attach
  26712.     select @cmd = quotename(@temp_db_name) + '.dbo.sp_MSprepare_sub_for_detach'
  26713.     
  26714.     exec @retcode = @cmd @subscriber_srvid = @subscriber_srvid, @subscriber_db = @subscriber_db
  26715.     if @retcode<>0 or @@error<>0
  26716.     begin
  26717.         select @retcode = 1
  26718.         goto Cleanup
  26719.     end
  26720.  
  26721.     -- Shink the size of the temp db before detach
  26722.     DBCC SHRINKDATABASE (@temp_db_name, 10)
  26723.     if @@error <> 0
  26724.         goto Cleanup
  26725.  
  26726.     -- detach the database
  26727.     -- Wait for the db to be closed
  26728.     WAITFOR DELAY '00:00:00.500'
  26729.     exec @retcode = sp_detach_db @temp_db_name
  26730.     if @retcode<>0 or @@error<>0
  26731.     begin
  26732.         select @retcode = 1
  26733.         goto Cleanup
  26734.     end
  26735.  
  26736.     -- Delete the log file to save disk space
  26737.     if @temp_log_path is not null
  26738.     begin
  26739.         select @cmd = 'del ' + quotename(@temp_log_path,'"') 
  26740.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26741.         set @temp_log_path = null
  26742.     end
  26743.  
  26744.     -- Compress the file
  26745.     exec @retcode = master..xp_makecab
  26746.         @cabfilename = @filename,
  26747.         @compression_mode ='mszip',
  26748.         @verbose_level = 0,
  26749.         @filename1 = @temp_data_path
  26750.     if @retcode<>0 or @@error<>0
  26751.     begin
  26752.         select @retcode = 1
  26753.         goto Cleanup
  26754.     end
  26755.  
  26756.  
  26757. Cleanup:
  26758.     if exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  26759.         drop table dbo.MSreplication_restore_stage
  26760.  
  26761.  
  26762.     if exists (select * from master..sysdatabases where name = @temp_db_name collate database_default)
  26763.     begin
  26764.         select @cmd = 'drop database ' + quotename(@temp_db_name)
  26765.         exec (@cmd)
  26766.     end
  26767.  
  26768.     if @backup_path is not null
  26769.     begin
  26770.         select @cmd = 'del ' + quotename(@backup_path,'"') 
  26771.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26772.     end
  26773.  
  26774.     if @temp_data_path is not null
  26775.     begin
  26776.         select @cmd = 'del ' + quotename(@temp_data_path,'"') 
  26777.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26778.     end
  26779.  
  26780.     if @temp_log_path is not null
  26781.     begin
  26782.         select @cmd = 'del ' + quotename(@temp_log_path,'"') 
  26783.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26784.     end
  26785.  
  26786.     if @retcode <> 0
  26787.     begin
  26788.         select @cmd = 'del ' + quotename(@filename,'"') 
  26789.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26790.     end
  26791.  
  26792.     return @retcode
  26793. go
  26794. EXEC dbo.sp_MS_marksystemobject sp_copysubscription
  26795. GO
  26796.  
  26797. print ''
  26798. print 'Creating procedure sp_attachsubscription'
  26799. go
  26800. CREATE PROCEDURE sp_attachsubscription (
  26801. @dbname    sysname,
  26802. @filename nvarchar(260),
  26803. @subscriber_security_mode        int = NULL,                        /* 0 standard; 1 integrated */
  26804. @subscriber_login                sysname = NULL,
  26805. @subscriber_password            sysname = NULL
  26806. )
  26807. AS
  26808.  
  26809.     SET NOCOUNT ON
  26810.  
  26811.     /*
  26812.     ** Declarations.
  26813.     */
  26814.     declare @cmd nvarchar(4000)
  26815.     declare @retcode int
  26816.     DECLARE @platform_nt binary
  26817.     declare @copy_created bit
  26818.     declare @exists bit
  26819.  
  26820.     select @platform_nt = 0x1    
  26821.     select @retcode = 0
  26822.     select @copy_created = 0
  26823.     select @exists = 0
  26824.  
  26825.     -- Parameter check: @subscriber_security_mode
  26826.     if @subscriber_security_mode is null
  26827.     begin
  26828.         if ( platform() & @platform_nt ) = @platform_nt
  26829.             select @subscriber_security_mode = 1
  26830.         else
  26831.             select @subscriber_security_mode = 0
  26832.     end    
  26833.  
  26834.     if ( ( platform() & @platform_nt ) <> @platform_nt and @subscriber_security_mode = 1 )
  26835.     begin
  26836.         RAISERROR(21038, 16, -1)
  26837.         RETURN (1)
  26838.     end
  26839.  
  26840.     if (@subscriber_security_mode = 0) and (@subscriber_login IS NULL or rtrim(@subscriber_login) = '')
  26841.         set @subscriber_login = 'sa'
  26842.  
  26843.     -- Check to make sure the database does not exists.
  26844.     if exists (select * from master..sysdatabases where name = @dbname collate database_default)
  26845.     begin
  26846.         raiserror(20621, 16, -1, @dbname)
  26847.         return (1)
  26848.     end
  26849.  
  26850.     -- Check to see if users has permissions to create database
  26851.     -- permissions() have to be run in master to return create db permission.
  26852.     declare @pm int
  26853.     exec @retcode = master.dbo.sp_executesql N'select @pm = permissions()', N'@pm int output', @pm output
  26854.     if @@error <> 0 or @retcode <> 0
  26855.         return 1
  26856.     if @pm & 1 = 0
  26857.     begin
  26858.         raiserror(20618, 16, -1)
  26859.         return 1
  26860.     end
  26861.  
  26862.     -- Decompress the file
  26863.     -- We have to copy the file to another location first. 
  26864.     -- (cannot use source as destination')
  26865.     declare @temp_copy nvarchar(260)
  26866.     declare @file_dir nvarchar(260)
  26867.     declare @file_name nvarchar(260)
  26868.     declare @dir_cmd nvarchar(260)
  26869.     -- Set @drive_cmd if needed 
  26870.     -- Set temp copy to be the file directory first
  26871.     -- Note @file_dir include '\'
  26872.     if (charindex('\', @filename, 1) = 0)
  26873.     begin
  26874.         select @file_dir = ''
  26875.         select @file_name = @filename
  26876.     end
  26877.     else
  26878.     begin
  26879.         select @file_dir = left(@filename,len(@filename) + 1 - 
  26880.             charindex('\', reverse(@filename), 1))
  26881.         select @file_name = right(@filename, len(@filename) - len(@file_dir))
  26882.     end
  26883.     -- Get guid name
  26884.     declare @guid_name nvarchar(36)
  26885.     select @guid_name =  convert (nvarchar(36), newid())
  26886.     select @temp_copy = @file_dir + @guid_name + '.tmp'
  26887.  
  26888.  
  26889.     -- copy file
  26890.     select @cmd = 'copy "' + @filename + '" "' + @temp_copy + '"'
  26891.     exec @retcode = master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  26892.     if @@error <> 0 or @retcode <> 0
  26893.     begin
  26894.         raiserror(21248, 16, -1, @filename)
  26895.         select @retcode = 1
  26896.         goto Cleanup
  26897.     end    
  26898.  
  26899.     exec @retcode = dbo.sp_MSget_file_existence @temp_copy, @exists output
  26900.     if @@error <> 0 or @retcode <> 0
  26901.     begin
  26902.         select @retcode = 1
  26903.         goto Cleanup
  26904.     end
  26905.     if @exists = 0
  26906.     begin
  26907.         raiserror(21247, 16, -1, @temp_copy)        
  26908.         select @retcode = 1
  26909.         goto Cleanup
  26910.     end
  26911.  
  26912.     select @copy_created = 1
  26913.  
  26914.     -- decompress
  26915.     exec @retcode = master.dbo.xp_unpackcab 
  26916.         @cabfilename = @temp_copy,
  26917.         @destination_folder = @file_dir,
  26918.         @verbose_level = 0,
  26919.         @destination_file = @file_name,
  26920.         @suppress_messages = 1
  26921.         
  26922.     if @@error <> 0 
  26923.     begin
  26924.         select @retcode = 1
  26925.         goto Cleanup
  26926.     end
  26927.  
  26928.     if @retcode in (1030,1029,2005)
  26929.     begin
  26930.         raiserror(20609, 16, -1, @filename)
  26931.         select @retcode = 1
  26932.         goto Cleanup
  26933.     end    
  26934.     else if @retcode <> 0
  26935.     -- re-issue the command to get errors
  26936.     begin
  26937.         exec @retcode = master.dbo.xp_unpackcab 
  26938.             @cabfilename = @temp_copy,
  26939.             @destination_folder = @file_dir,
  26940.             @verbose_level = 0,
  26941.             @destination_file = @file_name,
  26942.             @suppress_messages = 0
  26943.         select @retcode = 1
  26944.         goto Cleanup
  26945.     end
  26946.  
  26947.     -- Attach
  26948.     exec @retcode = dbo.sp_attach_single_file_db
  26949.         @dbname = @dbname,
  26950.         @physname = @filename
  26951.     if @retcode<>0 or @@error<>0
  26952.     begin
  26953.         raiserror(21248, 16, -1, @filename)
  26954.         select @retcode = 1
  26955.         goto Cleanup
  26956.     end
  26957.  
  26958.  
  26959.     -- Prepare the database for detach. 2 things will be done
  26960.     -- 1. Set a flag to indicate that this is a prepare sub db for detach
  26961.     -- 2. For merge, create table to store sysservers info for later fixing up after attach
  26962.     select @cmd = quotename(@dbname) + '.dbo.sp_MSrestore_sub'
  26963.     exec @retcode = @cmd
  26964.         @subscriber_security_mode = @subscriber_security_mode,    
  26965.         @subscriber_login = @subscriber_login,
  26966.         @subscriber_password = @subscriber_password
  26967.     if @retcode<>0 or @@error<>0
  26968.     begin
  26969.         select @retcode = 1
  26970.         goto Cleanup
  26971.     end
  26972.  
  26973. Cleanup:
  26974.     if @retcode <> 0
  26975.     begin
  26976.         -- The files will be deleted if some thing failed. 
  26977.         if exists (select * from master..sysdatabases where name = @dbname collate database_default)
  26978.             begin
  26979.                 select @cmd = 'drop database ' + quotename(@dbname)
  26980.                 exec (@cmd)
  26981.             end                
  26982.     end
  26983.  
  26984.     if @temp_copy is not null
  26985.     begin
  26986.         -- Restore the original file, ignore errors
  26987.         if @retcode <> 0 and @copy_created = 1
  26988.         begin
  26989.             select @cmd = 'copy "' + @temp_copy + '" "' + @filename + '"'
  26990.             exec master.dbo.xp_cmdshell @cmd, NO_OUTPUT
  26991.         end
  26992.  
  26993.         -- Delete the temp file.
  26994.         select @cmd = 'del ' + quotename(@temp_copy,'"') 
  26995.         EXEC master..xp_cmdshell @cmd, NO_OUTPUT
  26996.     end
  26997.  
  26998.     return @retcode
  26999. go
  27000. EXEC dbo.sp_MS_marksystemobject sp_attachsubscription
  27001. GO
  27002.  
  27003.  
  27004. print ''
  27005. print 'Creating procedure sp_MSrestore_sub_merge'
  27006. go
  27007. CREATE PROCEDURE sp_MSrestore_sub_merge (
  27008.     @subscriber_security_mode        int,                        
  27009.     @subscriber_login                sysname,
  27010.     @subscriber_password            nvarchar(524)
  27011.     )
  27012. AS
  27013.  
  27014.     SET NOCOUNT ON
  27015.     declare @retcode             int
  27016.     declare @detached             int
  27017.     declare @attached             int
  27018.     DECLARE @publisher             sysname        /* Expression used in the cursor */
  27019.     DECLARE @publisher_db         sysname     /* Expression used in the cursor */
  27020.     DECLARE @publication         sysname      /* Expression used in the cursor */
  27021.     DECLARE @distributor        sysname        /* Expression used in the cursor */
  27022.     declare @subnickname        int
  27023.     declare @subid                 uniqueidentifier
  27024.     declare @detached_subid        uniqueidentifier
  27025.     declare @subscriber_srvid     int
  27026.     declare @subscriber_server    sysname
  27027.     declare @subscriber_db        sysname
  27028.     declare @enabled_for_syncmgr_int     int
  27029.     declare @enabled_for_syncmgr nvarchar(5)
  27030.     declare @retention            int
  27031.     declare @retention_date       datetime
  27032.     declare @pubid                 uniqueidentifier
  27033.     declare    @distributor_security_mode    int                        
  27034.     declare @distributor_login            sysname
  27035.     declare @distributor_password        nvarchar(524)
  27036.     declare    @publisher_security_mode    int                        
  27037.     declare @publisher_login            sysname
  27038.     declare @publisher_password            nvarchar(524)
  27039.  
  27040.     -- Initialization
  27041.     select @retcode = 0
  27042.     select @detached = 3
  27043.     select @attached = 4
  27044.     select @subscriber_srvid = 0
  27045.     select @subscriber_db = db_name()
  27046.  
  27047.     IF EXISTS (SELECT * from sysmergepublications where
  27048.         allow_subscription_copy = 0)
  27049.     BEGIN
  27050.         RAISERROR (21205, 16, -1, @publication)    
  27051.         RETURN (1)
  27052.     END
  27053.  
  27054.     /* Retention check : Make sure that the subscription copy is not too old */
  27055.     declare PC CURSOR LOCAL FAST_FORWARD for select DISTINCT p.name, p.pubid, p.retention from sysmergepublications p, sysmergesubscriptions s 
  27056.         where s.subid=p.pubid and s.pubid=p.pubid for read only
  27057.     open PC
  27058.     fetch PC into @publication, @pubid, @retention 
  27059.     
  27060.     WHILE (@@fetch_status <> -1)
  27061.         BEGIN
  27062.             /* Compute the retention period cutoff dates per publication */
  27063.             select @retention_date = dateadd(day, -@retention, getdate())
  27064.         
  27065.             if @retention is not NULL and @retention > 0
  27066.             begin
  27067.                 if not exists (select coldate from sysmergearticles , MSmerge_genhistory 
  27068.                     where nickname = art_nick 
  27069.                         and coldate > @retention_date 
  27070.                         and sysmergearticles.pubid = @pubid)
  27071.                     begin
  27072.                         RAISERROR (21307, 16, -1, @publication)
  27073.                         return (1)
  27074.                     end                                
  27075.             end
  27076.             fetch PC into @publication, @pubid, @retention
  27077.         END
  27078.  
  27079.     -- Touch up system tables for merge subscriptions
  27080.  
  27081.     -- Open a cursor for all subscriptions 
  27082.     DECLARE hCallsubscriptions CURSOR LOCAL FAST_FORWARD FOR
  27083.         SELECT subid, subscriber_server from sysmergesubscriptions
  27084.     FOR READ ONLY
  27085.     OPEN hCallsubscriptions
  27086.  
  27087.     FETCH hCallsubscriptions INTO @subid, @subscriber_server
  27088.     WHILE (@@fetch_status <> -1)
  27089.     BEGIN
  27090.         /*
  27091.         ** Validate that the subscriber is a valid server and has an entry in sysservers, else add it
  27092.         */
  27093.         select @subscriber_srvid = NULL
  27094.         select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber_server) collate database_default
  27095.         IF @subscriber_srvid IS NULL
  27096.             BEGIN
  27097.                 EXECUTE @retcode = dbo.sp_addserver @subscriber_server
  27098.                 IF @@error <> 0 OR @retcode <> 0
  27099.                     BEGIN
  27100.                         RAISERROR (14010, 16, -1)
  27101.                            RETURN (1)
  27102.                     END
  27103.                 select @subscriber_srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@subscriber_server) collate database_default
  27104.                 IF @subscriber_srvid IS NULL
  27105.                     BEGIN
  27106.                         RAISERROR (14010, 16, -1)
  27107.                            RETURN (1)
  27108.                     END
  27109.             END
  27110.  
  27111.     
  27112.         FETCH hCallsubscriptions INTO @subid, @subscriber_server
  27113.     END
  27114.  
  27115.     /*
  27116.     ** Touch up srvid of existing rows in sysmergesubscriptions that correspond
  27117.     ** to the subscription that is not attached. Note that this has to be a bulk 
  27118.     ** update since doing it a row at a time will cause the unique_pubsrvdb constaint
  27119.     ** in sysmergesubscriptions to be violated.
  27120.     */
  27121.     update sysmergesubscriptions 
  27122.         set srvid = fn_serverid(subscriber_server)
  27123.             where status <> @detached
  27124.     if @@ERROR <> 0
  27125.         goto Cleanup
  27126.             
  27127.  
  27128.     -- Open a cursor for all subscriptions that have a status of 'detached'
  27129.     DECLARE hCdetachedsubscriptions CURSOR LOCAL FAST_FORWARD FOR
  27130.         SELECT subid from sysmergesubscriptions where status = @detached 
  27131.     FOR READ ONLY
  27132.     OPEN hCdetachedsubscriptions
  27133.  
  27134.     FETCH hCdetachedsubscriptions INTO @detached_subid
  27135.     WHILE (@@fetch_status <> -1)
  27136.     BEGIN
  27137.         /*
  27138.         ** Select the srvid of the local server
  27139.         */
  27140.         select @subscriber_srvid = 0
  27141.  
  27142.         /* Generate a guid for the Subscriber ID */
  27143.         set @subid = newid()
  27144.  
  27145.         /* Look for existing nickname from any other subscription */
  27146.         exec dbo.sp_MSgetreplnick NULL, NULL , NULL,  @subnickname out
  27147.         if @@ERROR <> 0
  27148.             goto Cleanup
  27149.  
  27150.         /* Generate a new replica nickname from the @subid */
  27151.         if (@subnickname is null)
  27152.             begin
  27153.                 EXECUTE dbo.sp_MSgenreplnickname @subid, @subnickname output
  27154.                 if @@ERROR <> 0
  27155.                     goto Cleanup
  27156.             end                        
  27157.  
  27158.         /*
  27159.         ** Touch up existing rows in sysmergesubscriptions & MSmerge_replinfo.
  27160.         ** Set status of attached subsription as "attached"
  27161.         */
  27162.         update sysmergesubscriptions 
  27163.             set subid                 = @subid, 
  27164.                 srvid                 = @subscriber_srvid, 
  27165.                 subscriber_server         = @@servername,
  27166.                 db_name             = @subscriber_db, 
  27167.                 status                 = @attached,
  27168.                 login_name             = suser_sname(suser_sid())
  27169.             where subid = @detached_subid
  27170.         if @@ERROR <> 0
  27171.             goto Cleanup
  27172.             
  27173.         update MSmerge_replinfo set repid = @subid, 
  27174.             replnickname = @subnickname 
  27175.                 where repid = @detached_subid
  27176.         if @@ERROR <> 0
  27177.             goto Cleanup
  27178.     
  27179.         FETCH hCdetachedsubscriptions INTO @detached_subid 
  27180.     END
  27181.  
  27182.     /* Add pull subscription agents only if MSsubscription_properties exists */
  27183.     if exists (select * from sysobjects where name = 'MSsubscription_properties')
  27184.         begin            
  27185.             -- Add the agents for pull or anonymous subscriptions.
  27186.             DECLARE hCmergesubscription CURSOR LOCAL FAST_FORWARD FOR
  27187.                 SELECT publisher, publisher_db, publication, distributor, enabled_for_syncmgr,
  27188.                     distributor_security_mode, distributor_login, distributor_password,
  27189.                     publisher_security_mode, publisher_login, publisher_password
  27190.                     FROM MSsubscription_properties
  27191.                     -- only do this for merge subscriptions 
  27192.                     where publication_type = 2
  27193.                     --where publication is not NULL and
  27194.                     --    publication <> N'' and
  27195.                     --    subscription_type <> @push
  27196.             FOR READ ONLY
  27197.             OPEN hCmergesubscription
  27198.  
  27199.             FETCH hCmergesubscription INTO @publisher, 
  27200.                 @publisher_db, @publication, @distributor, @enabled_for_syncmgr_int,
  27201.                 @distributor_security_mode, @distributor_login, @distributor_password,
  27202.                 @publisher_security_mode, @publisher_login, @publisher_password
  27203.  
  27204.             WHILE (@@fetch_status <> -1)
  27205.             BEGIN
  27206.                 /* Enable the subscription to be synchronized via SyncMgr if the original one was */
  27207.                 if @enabled_for_syncmgr_int = 0
  27208.                     set @enabled_for_syncmgr = 'false'
  27209.                 else
  27210.                     set @enabled_for_syncmgr = 'true'
  27211.  
  27212.                 if @distributor_security_mode = 0 and @distributor_login is NULL
  27213.                     select @distributor_login = 'sa'
  27214.  
  27215.                 if @publisher_security_mode = 0 and @publisher_login is NULL
  27216.                     select @publisher_login = 'sa'
  27217.  
  27218.  
  27219.                 EXEC @retcode = master.dbo.xp_repl_help_connect @distributor_password OUTPUT
  27220.                 IF @@error <> 0 OR @retcode <> 0
  27221.                 begin
  27222.                     select @retcode = 1
  27223.                     goto Cleanup
  27224.                 end
  27225.  
  27226.                 EXEC @retcode = master.dbo.xp_repl_help_connect @publisher_password OUTPUT
  27227.                 IF @@error <> 0 OR @retcode <> 0
  27228.                 begin
  27229.                     select @retcode = 1
  27230.                     goto Cleanup
  27231.                 end
  27232.  
  27233.                 EXECUTE @retcode  = dbo.sp_addmergepullsubscription_agent 
  27234.                     @publisher = @publisher, 
  27235.                     @publisher_db = @publisher_db, 
  27236.                     @publication = @publication,
  27237.                     @distributor = @distributor,
  27238.                     @subscriber_security_mode = @subscriber_security_mode,    
  27239.                     @subscriber_login = @subscriber_login,
  27240.                     @subscriber_password = @subscriber_password,
  27241.                     @publisher_security_mode = @publisher_security_mode,    
  27242.                     @publisher_login = @publisher_login,
  27243.                     @publisher_password = @publisher_password,
  27244.                     @publisher_encrypted_password = 0,
  27245.                     @distributor_security_mode = @distributor_security_mode,    
  27246.                     @distributor_login = @distributor_login,
  27247.                     @distributor_password = @distributor_password,
  27248.                     @encrypted_password = 0,
  27249.                     @frequency_type  = 2 ,  /* 2== OnDemand */
  27250.                     @enabled_for_syncmgr = @enabled_for_syncmgr,    
  27251.                     @reserved = 'attach_subscription'
  27252.  
  27253.                 if @@error <> 0 or @retcode <> 0 
  27254.                 begin
  27255.                     select @retcode = 1
  27256.                     goto Cleanup
  27257.                 end
  27258.  
  27259.                 FETCH hCmergesubscription INTO @publisher, 
  27260.                     @publisher_db, @publication, @distributor, @enabled_for_syncmgr_int,
  27261.                     @distributor_security_mode, @distributor_login, @distributor_password,
  27262.                     @publisher_security_mode, @publisher_login, @publisher_password
  27263.             END
  27264.         end            
  27265.     else
  27266.         begin
  27267.             /* 
  27268.             ** Check to see if MSsubscription_properties table exists.
  27269.             ** If not, create it.
  27270.             */
  27271.             exec @retcode = dbo.sp_MScreate_sub_tables
  27272.                 @tran_sub_table = 0,
  27273.                 @property_table = 1,
  27274.                 @sqlqueue_table = 0
  27275.             if @@error <> 0 or @retcode <> 0 
  27276.             begin
  27277.                 select @retcode = 1
  27278.                 goto Cleanup
  27279.             end
  27280.         end
  27281.     return 0
  27282. Cleanup:
  27283.     return    1
  27284.     
  27285. go
  27286. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub_merge
  27287. GO
  27288.  
  27289.  
  27290.  
  27291. print ''
  27292. print 'Creating procedure sp_MSrestore_sub_tran'
  27293. go
  27294. CREATE PROCEDURE sp_MSrestore_sub_tran (
  27295.     @subscriber_security_mode        int,                        
  27296.     @subscriber_login                sysname,
  27297.     @subscriber_password            nvarchar(524)
  27298.     )
  27299. AS
  27300.  
  27301.     SET NOCOUNT ON
  27302.  
  27303.     /*
  27304.     ** Declarations.
  27305.     */
  27306.     declare @push int
  27307.     declare @retcode int
  27308.     DECLARE @publisher sysname          /* Expression used in the cursor */
  27309.     DECLARE @publisher_db sysname     /* Expression used in the cursor */
  27310.     DECLARE @publication sysname      /* Expression used in the cursor */
  27311.  
  27312.     -- Initialization
  27313.     select @push = 0
  27314.     select @retcode = 0
  27315.  
  27316.  
  27317.     -- Reset agent_id and anonymous agent id and time
  27318.     update MSreplication_subscriptions set agent_id = NULL, subid = NULL,
  27319.         distribution_agent = NULL, time = getdate()
  27320.     if @@error <> 0
  27321.     begin
  27322.         select @retcode = 1
  27323.         goto Cleanup
  27324.     end
  27325.  
  27326.     -- Set attach_state value
  27327.     -- It is only used by pull subscription.
  27328.     -- The attach state is "attached but not processed".
  27329.     update MSsubscription_agents set attach_state = 1
  27330.  
  27331.     -- Add the agents for pull or anonymous subscriptions. 
  27332.     DECLARE hCsubscription CURSOR LOCAL FAST_FORWARD FOR
  27333.         SELECT publisher, publisher_db, publication    
  27334.             FROM MSreplication_subscriptions where 
  27335.                 publication is not NULL and
  27336.                 publication <> N'' and
  27337.                 subscription_type <> @push
  27338.     FOR READ ONLY
  27339.     OPEN hCsubscription
  27340.  
  27341.     FETCH hCsubscription INTO @publisher, 
  27342.         @publisher_db, @publication
  27343.     WHILE (@@fetch_status <> -1)
  27344.     BEGIN
  27345.         EXECUTE @retcode  = dbo.sp_addpullsubscription_agent 
  27346.             @publisher = @publisher, 
  27347.             @publisher_db = @publisher_db, 
  27348.             @publication = @publication, 
  27349.             @subscriber_security_mode = @subscriber_security_mode,    
  27350.             @subscriber_login = @subscriber_login,
  27351.             @subscriber_password = @subscriber_password,
  27352.             @frequency_type  = 2 ,  /* 2== OnDemand */
  27353.             @reserved = 'no_change_to_properties'
  27354.  
  27355.         if @@error <> 0 or @retcode <> 0 
  27356.         begin
  27357.             select @retcode = 1
  27358.             goto Cleanup
  27359.         end
  27360.  
  27361.         FETCH hCsubscription INTO @publisher, 
  27362.             @publisher_db, @publication
  27363.     END
  27364.  
  27365. Cleanup:
  27366.     -- Nothing to cleanup
  27367.     return    @retcode
  27368. go
  27369. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub_tran
  27370. GO
  27371.  
  27372. print ''
  27373. print 'Creating procedure sp_MSrestore_sub'
  27374. go
  27375. CREATE PROCEDURE sp_MSrestore_sub (
  27376.     @subscriber_security_mode        int,                        
  27377.     @subscriber_login                sysname,
  27378.     @subscriber_password            nvarchar(524)
  27379.     )
  27380. AS
  27381.  
  27382.     SET NOCOUNT ON
  27383.  
  27384.     /*
  27385.     ** Declarations.
  27386.     */
  27387.     declare @retcode int
  27388.  
  27389.     -- Initialization
  27390.     select @retcode = 0
  27391.  
  27392.     if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  27393.     begin
  27394.         exec @retcode = dbo.sp_MSrestore_sub_tran
  27395.             @subscriber_security_mode = @subscriber_security_mode,    
  27396.             @subscriber_login = @subscriber_login,
  27397.             @subscriber_password = @subscriber_password
  27398.  
  27399.         if @@error <> 0 or @retcode <> 0
  27400.         begin
  27401.             select @retcode = 1
  27402.             goto Cleanup
  27403.         end
  27404.     end
  27405.     if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  27406.     begin
  27407.         exec @retcode = dbo.sp_MSrestore_sub_merge
  27408.             @subscriber_security_mode = @subscriber_security_mode,    
  27409.             @subscriber_login = @subscriber_login,
  27410.             @subscriber_password = @subscriber_password
  27411.         if @@error <> 0 or @retcode <> 0
  27412.         begin
  27413.             select @retcode = 1
  27414.             goto Cleanup
  27415.         end
  27416.     end
  27417.  
  27418. Cleanup:
  27419.     if exists (select * from sysobjects where name = 'MSreplication_restore_stage')
  27420.         drop table MSreplication_restore_stage
  27421.  
  27422.     return    @retcode
  27423. go
  27424. EXEC dbo.sp_MS_marksystemobject sp_MSrestore_sub
  27425. GO
  27426.  
  27427.  
  27428. raiserror('Creating procedure sp_validatemergepullsubscription', 0,1)
  27429. GO
  27430.  
  27431. CREATE PROCEDURE sp_validatemergepullsubscription
  27432.     (@publication            sysname,
  27433.      @publisher                sysname,
  27434.      @publisher_db            sysname,
  27435.      @level                    tinyint
  27436.      ) AS
  27437.  
  27438.     declare @subscriber_srvid        int
  27439.     declare @retcode                int
  27440.     declare @pubid                    uniqueidentifier
  27441.     declare @subscriber                sysname
  27442.     declare @subscriber_db            sysname
  27443.     /*
  27444.     ** Security Check
  27445.     */
  27446.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  27447.     IF @@ERROR <> 0 or @retcode <> 0
  27448.         return (1)
  27449.  
  27450.     select @subscriber = @@SERVERNAME, @subscriber_db=db_name()
  27451.     select @subscriber_srvid = srvid from master..sysservers where LOWER(srvname)=LOWER(@subscriber) collate database_default
  27452.  
  27453.     select @pubid=pubid from sysmergepublications where LOWER(publisher)=LOWER(@publisher) and publisher_db=@publisher_db and name=@publication
  27454.     if @pubid is NULL
  27455.         begin
  27456.             raiserror (20026, 16, -1, @publication)
  27457.             return (1)
  27458.         end
  27459.     if @level <0 or @level > 3
  27460.         begin
  27461.             raiserror(21184, 16, -1, '@level', '1', '2','3')
  27462.             return (1)
  27463.         end
  27464.  
  27465.     if not exists (select * from sysmergesubscriptions where pubid=@pubid and db_name=@subscriber_db and srvid=@subscriber_srvid)
  27466.         begin
  27467.             raiserror(14055, 16, -1)
  27468.             return (1)
  27469.         end
  27470.  
  27471.     update sysmergesubscriptions set validation_level=@level where pubid=@pubid and db_name=@subscriber_db and srvid=@subscriber_srvid
  27472.     if @@ERROR<>0
  27473.         return (1)
  27474.     return (0)
  27475.  
  27476. go
  27477. exec dbo.sp_MS_marksystemobject sp_validatemergepullsubscription
  27478. go
  27479. grant exec on dbo.sp_validatemergepullsubscription to public
  27480. go
  27481.  
  27482.  
  27483. print ''
  27484. print 'Creating procedure sp_MSprepare_sub_for_detach'
  27485. go
  27486. CREATE PROCEDURE sp_MSprepare_sub_for_detach 
  27487.     @subscriber_srvid     int,
  27488.     @subscriber_db          sysname
  27489. as
  27490.     set nocount on
  27491.     declare @detached     int
  27492.     select @detached = 3
  27493.     
  27494.     -- Stage: attach and restore subscription.
  27495.     update dbo.MSreplication_restore_stage set stage_id = 2
  27496.     if @@error <> 0
  27497.         return 1
  27498.  
  27499.     /* Touch up the merge subscriptions for detach */
  27500.     if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  27501.     begin            
  27502.         /* Mark all subscriptions to have a status of detached */
  27503.         update sysmergesubscriptions set status = @detached where srvid = @subscriber_srvid and db_name = @subscriber_db
  27504.         if @@error <> 0
  27505.             return 1
  27506.     end        
  27507.     if exists (select * from sysobjects where name = 'MSsub_identity_range')
  27508.     begin
  27509.         -- Set range to 0 so that the attached db will get new ranges
  27510.         -- Refer to sp_MSsub_check_identity
  27511.         update MSsub_identity_range set range = 0
  27512.         if @@error <> 0
  27513.             return 1
  27514.     end    
  27515. go
  27516. EXEC dbo.sp_MS_marksystemobject sp_MSprepare_sub_for_detach
  27517. GO
  27518.  
  27519. print ''
  27520. print 'Creating procedure sp_MSsub_check_identity'
  27521. go
  27522. CREATE PROCEDURE sp_MSsub_check_identity
  27523. @lower_bound_id int
  27524. as
  27525.     declare @retcode int
  27526.     declare @cmd nvarchar(1000)
  27527.     declare @objid int, @threshhold bigint, @range bigint, @next_seed bigint
  27528.     declare    @last_seed bigint, @identity_so_far bigint, @threshold int
  27529.     declare @table_name sysname
  27530.     declare @qualname nvarchar(512)
  27531.  
  27532.     --  Security Check
  27533.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  27534.     IF @@ERROR <> 0 or @retcode <> 0
  27535.     RETURN(1)
  27536.  
  27537.     -- This proc will be called by distribution agent called repeatedly until
  27538.     -- one result returned
  27539.     if exists (select * from sysobjects where name = 'MSsub_identity_range')
  27540.     begin
  27541.         while 1 = 1
  27542.         begin
  27543.             select @objid = null
  27544.             select top 1 @objid = objid from MSsub_identity_range where
  27545.                 objid > @lower_bound_id 
  27546.                 order by objid ASC
  27547.             if @objid is null
  27548.                 break
  27549.  
  27550.             select @lower_bound_id = @objid
  27551.             -- Since we don't always clean up the subscriber, Skipping invalid entry.
  27552.             if object_name(@objid) is null 
  27553.                 continue
  27554.             if objectproperty(@objid, 'TableHasIdentity') <> 1
  27555.                 continue
  27556.  
  27557.             exec sp_MSget_qualified_name @objid, @qualname OUTPUT
  27558.  
  27559.             select @range = range, @last_seed = last_seed, @threshold = threshold from 
  27560.                 MSsub_identity_range where objid=@objid
  27561.                 
  27562.             if @range = 0
  27563.                 -- First time after initial bcp, always request a new range
  27564.                 -- return this object
  27565.                 break
  27566.             else
  27567.             begin                 
  27568.  
  27569.                 -- Leave one slot unused. This is to prevent violation of primary key constraint
  27570.                 -- if the next value is used by a subscriber and the publisher has received it.
  27571.                 -- It seems the pk constraint will be validated before this check.
  27572.                 declare @actual_range int
  27573.                 if @range > 0
  27574.                     select @actual_range = @range - 1
  27575.                 else
  27576.                     select @actual_range = @range + 1
  27577.  
  27578.                 select @identity_so_far = ident_current(@qualname)
  27579.  
  27580.                 if 100*(@identity_so_far - @last_seed)/@actual_range >= @threshold
  27581.                     -- Need new range
  27582.                     break
  27583.             end
  27584.  
  27585.             select @lower_bound_id = @objid
  27586.         end
  27587.     end
  27588.     select @table_name = object_name(@objid)            
  27589.  
  27590.     -- Return nothing if @table_name is null, which means no more table needs to be adjust
  27591.     select 'objid' = @objid, 'table_name' = @table_name where @objid is not null    
  27592. go
  27593. EXEC dbo.sp_MS_marksystemobject sp_MSsub_check_identity
  27594. GO
  27595.  
  27596. print ''
  27597. print 'Creating procedure sp_MSsub_cleanup_orphans'
  27598. go
  27599. CREATE PROCEDURE sp_MSsub_cleanup_orphans AS
  27600.  
  27601.  
  27602.     /*
  27603.     ** Security Check
  27604.     */
  27605.     -- Internal sp, not granted to public.
  27606.     -- Ignore all errrors
  27607.  
  27608.        if exists (select * from sysobjects where name = 'MSreplication_objects')
  27609.     begin
  27610.         delete MSreplication_objects where not exists (select * from sysobjects
  27611.             where name = object_name)
  27612.         if not exists (select * from MSreplication_objects)
  27613.             drop table MSreplication_objects
  27614.     end
  27615.             
  27616.        if exists (select * from sysobjects where name = 'MSsub_identity_range')
  27617.     begin
  27618.         delete MSsub_identity_range where not exists (select * from sysobjects
  27619.             where id = objid)
  27620.         if not exists (select * from MSsub_identity_range)
  27621.             drop table MSsub_identity_range
  27622.     end
  27623. GO
  27624. EXEC dbo.sp_MS_marksystemobject sp_MSsub_cleanup_orphans
  27625. GO
  27626.  
  27627. print ''
  27628. print 'Creating procedure sp_MSsub_cleanup_prop_table'
  27629. go
  27630. CREATE PROCEDURE sp_MSsub_cleanup_prop_table AS
  27631.  
  27632.  
  27633.     /*
  27634.     ** Security Check
  27635.     */
  27636.     -- Internal sp, not granted to public.
  27637.     -- Ignore all errrors
  27638.     declare @drop_table bit
  27639.  
  27640.     -- Init to drop table
  27641.     select @drop_table = 1
  27642.  
  27643.        if exists (select * from sysobjects where name = 'MSreplication_subscriptions')
  27644.     begin
  27645.         if exists (select * from MSreplication_subscriptions where 
  27646.             subscription_type <> 0)
  27647.             select @drop_table = 0
  27648.     end
  27649.             
  27650.        if exists (select * from sysobjects where name = 'sysmergesubscriptions')
  27651.     begin
  27652.         if exists (select * from sysmergesubscriptions where subid <> pubid and 
  27653.             db_name = db_name() and 
  27654.             subscriber_server = convert(sysname, SERVERPROPERTY('ServerName')) collate database_default and
  27655.             subscription_type <> 0)
  27656.             select @drop_table = 0
  27657.     end
  27658.  
  27659.     if @drop_table = 1
  27660.         drop table dbo.MSsubscription_properties
  27661.  GO
  27662. EXEC dbo.sp_MS_marksystemobject sp_MSsub_cleanup_prop_table
  27663. GO
  27664.  
  27665. print ''
  27666. print 'Creating procedure sp_MSreseed'
  27667. go
  27668.  
  27669. CREATE PROCEDURE sp_MSreseed(
  27670. @objid                int,
  27671. @next_seed            bigint,
  27672. @range                 bigint,
  27673. @is_publisher        int = 0,
  27674. @check_only         bit = 0,
  27675. @drop_only            bit = 0,
  27676. @initial_setting     bit = 0,
  27677. @bound_value        bigint = 0
  27678. )
  27679. AS
  27680. declare @min_value                bigint
  27681. declare @max_value                bigint
  27682. declare @constraintname            sysname
  27683. declare @artid                    uniqueidentifier
  27684. declare @min_str                nvarchar(20)
  27685. declare @identity_column        sysname
  27686. declare @colid                    int
  27687. declare @colname                sysname
  27688. declare @max_str                nvarchar(20)
  27689. declare @owner                    sysname
  27690. declare @tablename                sysname
  27691. declare @qualname                nvarchar(270)
  27692. declare @dbname                    sysname
  27693. declare @prefix                    sysname
  27694.  
  27695. SET NOCOUNT ON
  27696.     select @prefix = 'repl_identity_range_'
  27697.     select @colid=1
  27698.     select @dbname=db_name()
  27699.     select @colname=name from syscolumns where colid=@colid and id = @objid
  27700.     while COLUMNPROPERTY(@objid, @colname, 'IsIdentity')=0 and @colname is not NULL
  27701.     begin
  27702.         select @colid = @colid + 1
  27703.         select @colname=name from syscolumns where colid=@colid and id = @objid
  27704.     end
  27705.     if @colname is NULL
  27706.     begin
  27707.         raiserror('there is no identity column in this table', 16, -1)
  27708.         return (1)
  27709.     end
  27710.     if @range > 0
  27711.     begin 
  27712.         select @min_value = @next_seed 
  27713.         if @initial_setting = 1
  27714.                     select @min_value = @bound_value - 1 -- allow for race condition with ident_current.             
  27715.         -- @next_seed + @range can be used by this db, but not other db.
  27716.         -- Leave one slot unused. This is to prevent violation of primary key constraint
  27717.         -- if the next value is used by a subscriber and the publisher has received it.
  27718.         -- It seems the pk constraint will be validated before this check.
  27719.         -- select @max_value = @next_seed + @range + 1
  27720.         select @max_value = @next_seed + @range
  27721.         select @next_seed=@next_seed + 1
  27722.     end
  27723.     else
  27724.     begin
  27725.         select @max_value = @next_seed 
  27726.         if @initial_setting = 1
  27727.                     select @max_value = @bound_value + 1 -- allow for race condition with ident_current.                     
  27728.         -- @next_seed + @range can be used by this db, but not other db.
  27729.         -- Leave one slot unused. This is to prevent violation of primary key constraint
  27730.         -- if the next value is used by a subscriber and the publisher has received it.
  27731.         -- It seems the pk constraint will be validated before this check.
  27732.         -- select @min_value = @next_seed + @range - 1
  27733.         select @min_value = @next_seed + @range
  27734.         select @next_seed=@next_seed - 1
  27735.     end
  27736.  
  27737.     select @min_str = convert(nvarchar, @min_value)
  27738.     select @max_str = convert(nvarchar, @max_value)
  27739.     select @owner = user_name(uid) from sysobjects where id = @objid
  27740.     select @tablename = object_name(@objid)
  27741.     select @qualname = QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
  27742.  
  27743.     if @check_only = 0
  27744.     begin 
  27745.         DBCC CHECKIDENT(@qualname, RESEED, @next_seed) with no_infomsgs
  27746.         if @@ERROR<>0
  27747.                 return (1)
  27748.     end
  27749.  
  27750.     if @is_publisher < 0
  27751.     begin
  27752.         -- Used by tran
  27753.         -- Publisher side constraint maybe transfered to subscriber.
  27754.         -- If so, it will be dropped with code below.
  27755.         select @constraintname = NULL
  27756.           select @constraintname = name from sysobjects where name like @prefix + 'tran_[0-9]%' and 
  27757.             xtype='C' and
  27758.             parent_obj = @objid
  27759.         if @constraintname is not null
  27760.         begin
  27761.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  27762.             if @@ERROR<>0
  27763.                 return (1)
  27764.         end
  27765.           select @constraintname = @prefix + 'tran_' + convert(nvarchar(10), @objid)
  27766.     end
  27767.     else
  27768.     begin 
  27769.         -- Used by merge
  27770.         select @artid=artid from sysmergearticles where objid=@objid
  27771.         select @constraintname = @prefix + 'pub_' + convert(nvarchar(36), @artid)
  27772.         select @constraintname = REPLACE(@constraintname, '-', '_')
  27773.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  27774.         begin
  27775.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  27776.             if @@ERROR<>0
  27777.                 return (1)
  27778.         end
  27779.         select @constraintname = @prefix + 'repub_' + convert(nvarchar(36), @artid)
  27780.         select @constraintname = REPLACE(@constraintname, '-', '_')
  27781.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  27782.         begin
  27783.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  27784.             if @@ERROR<>0
  27785.                 return (1)
  27786.         end
  27787.         select @constraintname = @prefix + 'sub_' + convert(nvarchar(36), @artid)
  27788.         select @constraintname = REPLACE(@constraintname, '-', '_')
  27789.         if exists (select * from sysobjects where name = @constraintname and xtype='C')
  27790.         begin
  27791.             exec ('alter table '+ @qualname + ' drop constraint ' + @constraintname)
  27792.             if @@ERROR<>0
  27793.                 return (1)
  27794.         end    
  27795.         if @is_publisher=1
  27796.             select @constraintname = @prefix + 'pub_' + convert(nvarchar(36), @artid)
  27797.         else 
  27798.             if @is_publisher = 2
  27799.                 select @constraintname = @prefix + 'repub_' + convert(nvarchar(36), @artid)
  27800.             else
  27801.                 select @constraintname = @prefix + 'sub_' + convert(nvarchar(36), @artid)
  27802.         select @constraintname = REPLACE(@constraintname, '-', '_')
  27803.     end
  27804.  
  27805.     -- Don't add new constraint if only drop is needed.
  27806.     if @drop_only = 1
  27807.         return (0)
  27808.  
  27809.     exec ('alter table '+ @qualname + ' with NOCHECK add CONSTRAINT ' + @constraintname + ' check NOT FOR REPLICATION ( ' + @colname + ' > ' 
  27810.         + @min_str + ' and ' + @colname + ' < ' + @max_str + ')')
  27811.     if @@ERROR<>0
  27812.         return (1)
  27813.     return (0)
  27814. GO
  27815. EXEC dbo.sp_MS_marksystemobject sp_MSreseed
  27816. GO
  27817.  
  27818. print ''
  27819. print 'Creating procedure sp_MSsub_set_identity'
  27820. go
  27821. CREATE PROCEDURE sp_MSsub_set_identity
  27822. @objid int,
  27823. @threshold int,
  27824. @range bigint,
  27825. @next_seed bigint
  27826. as
  27827.     declare @retcode int
  27828.  
  27829.     --  Security Check
  27830.     EXEC @retcode = dbo.sp_MSreplcheck_subscribe
  27831.     IF @@ERROR <> 0 or @retcode <> 0
  27832.     RETURN(1)
  27833.  
  27834.     -- Stored last_seed in @next_seed
  27835.     select @next_seed = @next_seed - @range
  27836.  
  27837.     update MSsub_identity_range set 
  27838.         last_seed = @next_seed,
  27839.         threshold = @threshold,
  27840.         range = @range
  27841.         where objid = @objid
  27842.     IF @@ERROR <> 0
  27843.         return 1
  27844.     -- RESEED and change constraint
  27845.     exec @retcode = dbo.sp_MSreseed
  27846.         @objid = @objid,
  27847.         @next_seed = @next_seed,
  27848.         @range = @range,
  27849.         @is_publisher = -1
  27850.     IF @@ERROR <> 0 OR @retcode <> 0
  27851.         return 1
  27852. go
  27853. EXEC dbo.sp_MS_marksystemobject sp_MSsub_set_identity
  27854. GO
  27855.  
  27856. print ''
  27857. print 'Creating procedure sp_MSinstance_qv'
  27858. go
  27859. create procedure sp_MSinstance_qv @qv varchar(10)
  27860. as
  27861. begin
  27862.     declare @qv_value varchar(10)
  27863.     set nocount on
  27864.     -- -------------------------------------------------------------
  27865.     --
  27866.     -- BUGBUG 236535 : IA64 workaround
  27867.     --
  27868.     -- since xp_qv has not been ported yet - detect the
  27869.     -- the platform and preset the config for IA64 servers
  27870.     --
  27871.     -- NOTE : this code should be later cleaned up
  27872.     -- once SETUP is completely functional on IA64
  27873.     --
  27874.     -- -------------------------------------------------------------
  27875.     declare @fia64 bit
  27876.     
  27877.     create table #tosversion ( propid int, propname sysname collate database_default, value int null, charvalue nvarchar(255) collate database_default)
  27878.     insert into #tosversion (propid, propname, value, charvalue)
  27879.         exec master.dbo.xp_msver N'Platform'
  27880.     
  27881.     select @fia64 = case when patindex(N'%IA64%', charvalue) != 0 then 1 else 0 end
  27882.     from #tosversion
  27883.  
  27884.     if (@fia64 = 1)
  27885.     begin
  27886.         select @qv_value = 0
  27887.     end
  27888.     else
  27889.     begin
  27890.         if serverproperty('instancename') is null
  27891.             exec @qv_value = master.dbo.xp_qv @qv    
  27892.         else
  27893.         begin
  27894.             declare @instance_name varchar(257)
  27895.             select @instance_name = cast(serverproperty('instancename') as varchar(257))
  27896.             exec @qv_value = master.dbo.xp_qv @qv, @instance_name
  27897.         end
  27898.     end
  27899.     -- -------------------------------------------------------------
  27900.     return @qv_value
  27901. end
  27902. go
  27903. EXEC dbo.sp_MS_marksystemobject sp_MSinstance_qv
  27904. GO
  27905.  
  27906. print ''
  27907. print 'Creating procedure sp_MSget_shared_agent'
  27908. go
  27909. CREATE PROCEDURE sp_MSget_shared_agent (
  27910.     @server_name sysname,
  27911.     @database_name sysname,
  27912.     @agent_type int,
  27913.     @publisher sysname = NULL -- Only usec by third party.
  27914.     ,@publisher_db sysname = NULL -- Only usec by third party.
  27915.     ) AS
  27916.  
  27917.     declare @server_id smallint
  27918.     select @server_id = srvid from master..sysservers where
  27919.         UPPER(srvname) = UPPER(@server_name) collate database_default
  27920.     -- push agents to SQL publications
  27921.     if @agent_type = 0
  27922.     begin
  27923.         if object_id('syssubscriptions') is not null
  27924.         begin
  27925.             select top 1 N'job_id' = distribution_jobid from syssubscriptions s, sysarticles a,
  27926.                 syspublications p where
  27927.                 srvid = @server_id and
  27928.                 dest_db = @database_name and
  27929.                 subscription_type = 0 and
  27930.                 independent_agent = 0 and
  27931.                 s.artid = a.artid and
  27932.                 p.pubid = a.pubid
  27933.         end
  27934.     end
  27935.     -- push agents to third party
  27936.     else if @agent_type = 1
  27937.     begin
  27938.         if object_id('MSsubscriptions') is not null
  27939.         begin
  27940.             declare @publisher_id smallint
  27941.             select top 1 @publisher_id from master..sysservers where
  27942.                 UPPER(srvname) = UPPER(@publisher) collate database_default
  27943.             select top 1 N'job_id' = job_id from MSdistribution_agents where
  27944.                 subscriber_id = @server_id and
  27945.                 subscriber_db = @database_name and
  27946.                 publication = N'ALL' and
  27947.                 publisher_id = @publisher_id and
  27948.                 publisher_db = @publisher_db and
  27949.                 subscription_type = 0
  27950.         end
  27951.     end
  27952.     else if @agent_type = 2
  27953.     begin
  27954.         if object_id('MSreplication_subscriptions') is not null
  27955.         begin
  27956.             -- For subscriptions added through Active X control
  27957.             -- where there's no local agent created, we still don't
  27958.             -- want to create new agent.
  27959.             select top 1 N'job_id' = agent_id from MSreplication_subscriptions where
  27960.                 UPPER(publisher) = UPPER(@server_name) and
  27961.                 publisher_db = @database_name and
  27962.                 independent_agent = 0 and
  27963.                 subscription_type in (1,2)
  27964.         end
  27965.     end
  27966. GO
  27967. EXEC dbo.sp_MS_marksystemobject sp_MSget_shared_agent
  27968. GO
  27969.  
  27970. print ''
  27971. print 'Creating procedure sp_MSrepl_backup_start'
  27972. go
  27973. create procedure sp_MSrepl_backup_start
  27974. as
  27975.     declare @sync_bit int
  27976.     declare @dist_bit int
  27977.  
  27978.     set nocount on
  27979.     
  27980.     set @sync_bit = 32
  27981.     set @dist_bit = 16
  27982.  
  27983.     -- If this is a distribution database and it is marked by 'sync with backup'
  27984.     if exists (select * from master.dbo.sysdatabases where
  27985.         name = db_name() collate database_default and
  27986.         category & (@sync_bit | @dist_bit) = @sync_bit | @dist_bit)
  27987.     begin
  27988.         update MSrepl_backup_lsns set next_xact_id = t2.xact_id, next_xact_seqno = m.xact_seqno from 
  27989.             (select tm.publisher_database_id, max(tm.xact_seqno) from 
  27990.                 -- max seqno of xacts not involved in partial tran processing
  27991.                 (select t.publisher_database_id, max(substring(t.xact_seqno, 1, 10)) from 
  27992.                     MSrepl_transactions t where
  27993.                     not t.xact_id = 0x0 
  27994.                     group by t.publisher_database_id, substring(t.xact_seqno, 1, 10)
  27995.                     having count(t.xact_seqno) < 2
  27996.                 union
  27997.                 -- max seqno of xacts involved in and completed partial tran processing
  27998.                 select t.publisher_database_id, max(substring(xact_seqno, 1, 10)) from
  27999.                     MSrepl_transactions t where
  28000.                     not t.xact_id = 0x0 
  28001.                     and t.xact_id = substring(t.xact_seqno, 1, 10)
  28002.                     group by t.publisher_database_id
  28003.                 )as tm(publisher_database_id, xact_seqno) -- derived table containing up to 2 rows per publication_database_id
  28004.             group by tm.publisher_database_id -- derived table containing up to 1 row per publication_database_id
  28005.             )as m(publisher_database_id, xact_seqno), 
  28006.             MSrepl_transactions t2                
  28007.         where m.publisher_database_id = MSrepl_backup_lsns.publisher_database_id and
  28008.                 t2.publisher_database_id = MSrepl_backup_lsns.publisher_database_id and
  28009.                 t2.xact_seqno    = m.xact_seqno
  28010.         if @@error <> 0
  28011.             return 1
  28012.     end
  28013.  
  28014.     return 0
  28015. go
  28016. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_backup_start
  28017. GO
  28018.  
  28019. print ''
  28020. print 'Creating procedure sp_MSrepl_backup_complete'
  28021. go
  28022. create procedure sp_MSrepl_backup_complete
  28023. as
  28024.     declare @sync_bit int
  28025.     declare @dist_bit int
  28026.  
  28027.     set nocount on
  28028.     
  28029.     set @sync_bit = 32
  28030.     set @dist_bit = 16
  28031.  
  28032.     -- If this is a distribution database and it is marked by 'sync with backup'
  28033.     if exists (select * from master.dbo.sysdatabases where
  28034.         name = db_name() collate database_default and
  28035.         category & (@sync_bit | @dist_bit) = @sync_bit | @dist_bit)
  28036.     begin
  28037.         update MSrepl_backup_lsns set valid_xact_id = next_xact_id, 
  28038.             valid_xact_seqno = next_xact_seqno 
  28039.         if @@error <> 0
  28040.             return 1
  28041.     end
  28042.     return 0
  28043. go
  28044. EXEC dbo.sp_MS_marksystemobject sp_MSrepl_backup_complete
  28045. GO
  28046.  
  28047. --
  28048. -- sp_MSadd_compensating_cmd
  28049. --
  28050. -- Proc executed from publisher that POSTS COMPENSATING command into 
  28051. -- Publisher Log OR Inserts COMPENSATING command into Distributor 
  28052. -- command table for a given subscriber/subscriberdb based on the mode
  28053. --
  28054. -- Parameters:
  28055. --    @orig_srv            originating subscriber
  28056. --    @orig_db            subscriber db
  28057. --    @command            command or command fragment (max 4000 chars)
  28058. --    @article_id         article id
  28059. --    @publication_id        publication id
  28060. --    @cmdstate            flag to indicate command fragment - to handle case
  28061. --                        where actual commands len exceeds 4000 chars
  28062. --    @mode                mode of operation, 0 = POST IN PUBLISHER LOG
  28063. --                        1 = INSERT IN DISTRIBUTOR COMMAND TABLE
  28064. --    @setprefix            flag to indicate if we should prefix command with originator info
  28065. --
  28066. print ''
  28067. print 'Creating procedure sp_MSadd_compensating_cmd'
  28068. go
  28069. CREATE PROCEDURE sp_MSadd_compensating_cmd(
  28070.     @orig_srv            sysname,
  28071.     @orig_db            sysname,
  28072.     @command            nvarchar(4000),
  28073.     @article_id         int,
  28074.     @publication_id        int,
  28075.     @cmdstate            bit=0,
  28076.     @mode                int=0,
  28077.     @setprefix            bit=1
  28078. )    
  28079. AS
  28080. BEGIN
  28081.     set nocount on
  28082.     declare     
  28083.  
  28084.     --
  28085.     -- variable declarations for all modes
  28086.     --
  28087.                 @retcode            int,
  28088.                 @command_id         int,                -- command sequence
  28089.                 @partial_cmd         int,                -- partial command flag
  28090.                 @curlen                int,                -- current length to read
  28091.                 @start_index        int,                -- index to start reading
  28092.                 @max_fragment        int,                -- max binary fragment
  28093.                 @full_command        nvarchar(4000),        -- qualified command
  28094.                 @readsize            int,                -- read length chars or bytes based on mode
  28095.                 @mode_postpublog     int,
  28096.                 @mode_insdistcmd     int,
  28097.  
  28098.     --
  28099.     -- variable declarations specific to mode = 1
  28100.     --
  28101.  
  28102.                 @partial_cmdbit        bit,                -- partial command flag
  28103.                 @xact_seqno            varbinary(16),
  28104.                 @publisher_id         int,                -- publisher ID
  28105.                 @publisher_db        sysname,             -- publisher Db
  28106.                 @distributor        sysname,            -- distribution server
  28107.                 @distribdb            sysname,            -- distribution db
  28108.                 @charsize            int,                -- char size
  28109.                 @binary_cmd            varbinary(1024),    -- Binary converted command
  28110.                 @distproc            nvarchar(300)        -- RPC string
  28111.  
  28112.     --
  28113.     -- Security Check
  28114.     --
  28115.     exec @retcode = dbo.sp_MSreplcheck_publish
  28116.     if ((@@ERROR != 0) or (@retcode != 0))
  28117.         return(1)
  28118.  
  28119.     --
  28120.     -- Initialize
  28121.     --
  28122.     select         @mode_postpublog = 0,
  28123.                 @mode_insdistcmd = 1
  28124.  
  28125.     if (@mode NOT in (@mode_postpublog,@mode_insdistcmd))
  28126.         return(1)
  28127.  
  28128.     if (@mode = @mode_insdistcmd)
  28129.     begin
  28130.         select     @publisher_db = db_name(),
  28131.                 @publisher_id = srvid 
  28132.         from master.dbo.sysservers where UPPER(srvname) = UPPER(@@servername) collate database_default
  28133.  
  28134.         --
  28135.         -- Get distribution server information for remote RPC calls
  28136.         --
  28137.         EXECUTE @retcode = dbo.sp_helpdistributor @rpcsrvname = @distributor OUTPUT,
  28138.                                     @distribdb  = @distribdb OUTPUT
  28139.         if ((@@ERROR != 0) or (@retcode != 0))
  28140.             return(1)
  28141.         
  28142.         --
  28143.         -- Get the new xact_seqno
  28144.         --
  28145.         create table #new_xact_seqno ( seqno varbinary(16) NOT NULL )
  28146.         select @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSget_new_xact_seqno'
  28147.         insert into #new_xact_seqno
  28148.             EXECUTE @retcode = @distproc
  28149.                 @publisher_id = @publisher_id,
  28150.                 @publisher_db = @publisher_db,
  28151.                 @len = 14
  28152.         if ((@@ERROR != 0) or (@retcode != 0))
  28153.             return(1)
  28154.         select @xact_seqno = seqno from #new_xact_seqno    
  28155.         select @distproc = RTRIM(@distributor) + '.' + @distribdb +'.dbo.sp_MSadd_repl_command'
  28156.     end
  28157.     
  28158.     --
  28159.     -- Do the command insertion in a tran
  28160.     --
  28161.     select @full_command = case when (@setprefix = 1) then 
  28162.                                 QUOTENAME(@orig_srv) + QUOTENAME(@orig_db) + @command
  28163.                                 else @command end
  28164.     begin tran sp_MSadd_compensating_cmd
  28165.     
  28166.     --
  28167.     -- process the command
  28168.     -- for @mode_postpublog : just call sp_replpostcmd and that will do the job
  28169.     -- for @mode_insdistcmd : break the command into 1024 sized commands and add
  28170.     --
  28171.     if (@mode = @mode_postpublog)
  28172.     begin
  28173.         select     @partial_cmd = CASE when (@cmdstate = 1) then 1 else 0 END
  28174.         exec @retcode = dbo.sp_replpostcmd 
  28175.                 @partial_cmd,
  28176.                 @publication_id, 
  28177.                 @article_id, 
  28178.                 12,
  28179.                 @full_command
  28180.         if (@@ERROR != 0 or @retcode != 0)
  28181.             GOTO UNDO
  28182.     end
  28183.     else if (@mode = @mode_insdistcmd)
  28184.     begin
  28185.         select     @command_id = 0,
  28186.                 @start_index = 1,
  28187.                 @max_fragment = 1024,
  28188.                 @charsize = 2,
  28189.                 @curlen = LEN(@full_command),
  28190.                 @readsize = DATALENGTH(@full_command)
  28191.  
  28192.         while (@readsize > 0)
  28193.         begin
  28194.             -- set command id
  28195.             select @command_id = @command_id + 1
  28196.  
  28197.             -- Check if we have to process partial command
  28198.             if (@readsize > @max_fragment)
  28199.             begin
  28200.                 --
  28201.                 -- we have partial command to send
  28202.                 --
  28203.                 select @curlen = @max_fragment / @charsize
  28204.                 select     @partial_cmdbit = 1,
  28205.                         @binary_cmd = CAST(
  28206.                             SUBSTRING(@full_command, @start_index, @curlen)
  28207.                             AS varbinary(1024)),
  28208.                         @readsize = @readsize - @max_fragment
  28209.  
  28210.                 select @start_index = @start_index + @curlen
  28211.                 select @curlen = @readsize / @charsize
  28212.             end
  28213.             else
  28214.             begin
  28215.                 --
  28216.                 -- last fragment to send - end of command
  28217.                 -- check for command state - if state is PARTIAL_CMD (1)
  28218.                 -- then set the partial bit even though this is the last fragment
  28219.                 --
  28220.                 select     @partial_cmdbit = CASE when (@cmdstate = 1) then 1 else 0 END,
  28221.                         @binary_cmd = CAST(
  28222.                             SUBSTRING(@full_command, @start_index, @curlen) 
  28223.                             AS varbinary(1024)),
  28224.                         @readsize = 0
  28225.             end
  28226.                 
  28227.             --
  28228.             -- Add the command to the distributor
  28229.             --
  28230.             EXECUTE @retcode = @distproc
  28231.                 @publisher_id = @publisher_id, 
  28232.                 @publisher_db = @publisher_db, 
  28233.                 @xact_seqno = @xact_seqno,
  28234.                 @type = 12, 
  28235.                 @article_id = @article_id, 
  28236.                 @command_id = @command_id, 
  28237.                 @partial_command = @partial_cmdbit, 
  28238.                 @command = @binary_cmd
  28239.             if (@@ERROR != 0 or @retcode != 0)
  28240.                 GOTO UNDO
  28241.         end -- end of while loop
  28242.     end     -- end of if (@mode = @mode_insdistcmd)
  28243.  
  28244.     --
  28245.     -- Command(s) added successfully - End Tran
  28246.     --
  28247.     commit tran sp_MSadd_compensating_cmd
  28248.     return (0)
  28249.  
  28250. UNDO:
  28251.     --
  28252.     -- Error - Rollback
  28253.     --
  28254.     IF (@@TRANCOUNT > 0)
  28255.     begin
  28256.         ROLLBACK TRAN sp_MSadd_compensating_cmd
  28257.         if (@@TRANCOUNT > 0)
  28258.             COMMIT TRAN   
  28259.     end
  28260.     return (1)    
  28261. END
  28262. go
  28263. EXEC dbo.sp_MS_marksystemobject sp_MSadd_compensating_cmd
  28264. GO
  28265.  
  28266. --
  28267. --  System UDF fn_varbintohexstr
  28268. --     This function takes as input a varbinary
  28269. --    and returns the Hexadecimal representation string
  28270. --
  28271. create function dbo.fn_varbintohexstr (
  28272.     @pbinin varbinary(8000) )
  28273. returns nvarchar(4000)
  28274. as
  28275. begin
  28276.     declare @pstrout nvarchar(4000)
  28277.  
  28278.     select @pstrout = master.dbo.fn_varbintohexsubstring(1,@pbinin,1,0)
  28279.     return @pstrout
  28280. end
  28281. go
  28282.  
  28283. --
  28284. --  System UDF fn_varbintohexsubstring
  28285. --     This function takes as input a varbinary, and start offset and length
  28286. --    and returns the Hexadecimal representation string for the given substring
  28287. --
  28288. create function dbo.fn_varbintohexsubstring (
  28289.     @fsetprefix bit = 1        -- append '0x' to the output
  28290.     ,@pbinin varbinary(8000) -- input binary stream
  28291.     ,@startoffset int = 1     -- starting offset 
  28292.     ,@cbytesin int = 0         -- length of input to consider, 0 means total length
  28293. )
  28294. returns nvarchar(4000)
  28295. as
  28296. begin
  28297.     declare @pstrout nvarchar(4000)
  28298.         ,@i int
  28299.         ,@firstnibble int
  28300.         ,@secondnibble int
  28301.         ,@tempint int
  28302.         ,@hexstring char(16)
  28303.  
  28304.     --
  28305.     -- initialize and validate
  28306.     --
  28307.     if (@pbinin IS NOT NULL)
  28308.     begin    
  28309.         select @i = 0
  28310.                 ,@cbytesin = case when (@cbytesin > 0) then @cbytesin else DATALENGTH(@pbinin) end
  28311.                 ,@pstrout =  case when (@fsetprefix = 1) then N'0x' else N'' end
  28312.                 ,@hexstring = '0123456789abcdef'
  28313.  
  28314.         if ( ((@cbytesin * 2) + 2 > 4000) or ((@cbytesin * 2) + 2 < 1) )
  28315.             return NULL
  28316.  
  28317.         if ( ( @startoffset > @cbytesin ) or ( @startoffset < 1 ) )
  28318.             return NULL
  28319.             
  28320.         --
  28321.         -- do for each byte
  28322.         --
  28323.         while (@i < @cbytesin)
  28324.         begin
  28325.             --
  28326.             -- Each byte has two nibbles
  28327.             -- which we convert to character
  28328.             --
  28329.             select @tempint = cast(substring(@pbinin, @i + @startoffset, 1) as int)
  28330.             select @firstnibble = @tempint / 16
  28331.             select @secondnibble = @tempint % 16
  28332.  
  28333.             --
  28334.             -- we need to do an explicit cast with substring 
  28335.             -- for proper string conversion. 
  28336.             --
  28337.             select @pstrout = @pstrout +
  28338.                 cast(substring(@hexstring, (@firstnibble+1), 1) as nvarchar) +
  28339.                 cast(substring(@hexstring, (@secondnibble+1), 1) as nvarchar)
  28340.  
  28341.             select @i = @i + 1
  28342.         end
  28343.     end
  28344.     
  28345.     -- All done
  28346.     return @pstrout
  28347. end
  28348. go
  28349.  
  28350. -- system function : returns string corresponding to version number part of setup path
  28351. -- for the current instance 
  28352. raiserror(15339,-1,-1,'fn_MSsharedversion')
  28353. GO
  28354. CREATE FUNCTION dbo.fn_MSsharedversion ( @len_minorversion tinyint = 1 )
  28355.     RETURNS NVARCHAR(10)
  28356. AS
  28357. BEGIN
  28358.     
  28359.     DECLARE @version VARCHAR(20), @bookmark_begin SMALLINT, @bookmark_end SMALLINT
  28360.     DECLARE @tools_ver VARCHAR(20)
  28361.  
  28362.     SELECT @version = CONVERT( VARCHAR(20), SERVERPROPERTY( N'PRODUCTVERSION') )
  28363.  
  28364.      SELECT @bookmark_begin = CHARINDEX( '-', @version, 1) + 1
  28365.     SELECT @bookmark_end = CHARINDEX( '.', @version, @bookmark_begin + 3 ) 
  28366.     SELECT @version = SUBSTRING( @version, @bookmark_begin, @bookmark_end - @bookmark_begin )
  28367.  
  28368.     SELECT @tools_ver = RTRIM(LTRIM(LEFT( @version, CHARINDEX('.', @version, 1) - 1 ) + LEFT(RIGHT( @version, CHARINDEX('.', @version, @len_minorversion ) ), @len_minorversion )))
  28369.  
  28370.     RETURN @tools_ver
  28371.  
  28372. END
  28373. GO
  28374.  
  28375.  
  28376. -- system procedure : Get install and data root paths (instance aware)
  28377. raiserror(15339,-1,-1,'sp_MSget_setup_paths')
  28378. GO
  28379. CREATE PROCEDURE sp_MSget_setup_paths (
  28380. @sql_path    NVARCHAR(260) = NULL OUTPUT, 
  28381. @data_path    NVARCHAR(260) = NULL OUTPUT )
  28382. AS
  28383. BEGIN
  28384.     
  28385.     DECLARE @retcode INTEGER
  28386.     DECLARE @regkey NVARCHAR(260)
  28387.     
  28388.     SET NOCOUNT ON 
  28389.     
  28390.     declare @instance sysname
  28391.     select @instance = convert(sysname, SERVERPROPERTY('InstanceName'))
  28392.     select @regkey = 'SOFTWARE\Microsoft\'
  28393.     -- default installation
  28394.     if @instance is null
  28395.         SELECT @regkey = @regkey + 'MSSQLServer\Setup' 
  28396.     else
  28397.         SELECT @regkey = @regkey + 'Microsoft SQL Server\' + @instance + '\Setup'
  28398.  
  28399.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  28400.         @regkey,
  28401.         'SQLPath',
  28402.         @param = @sql_path OUTPUT
  28403.  
  28404.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) 
  28405.         RETURN (1)
  28406.     
  28407.     EXECUTE @retcode = master.dbo.xp_regread 'HKEY_LOCAL_MACHINE', 
  28408.         @regkey,
  28409.         'SQLDataRoot',
  28410.         @param = @data_path OUTPUT
  28411.  
  28412.     IF ( @retcode <> 0 ) or ( @@ERROR <> 0 ) 
  28413.         RETURN (1)
  28414.  
  28415.     RETURN (0)
  28416.  
  28417. END
  28418. GO
  28419.  
  28420. -- No parameter checking is performed in sp_MSremoveoffloadparameter
  28421. raiserror(15339,-1,-1,'sp_MSremoveoffloadparameter')
  28422. GO
  28423. CREATE PROCEDURE sp_MSremoveoffloadparameter (
  28424.     @job_id    VARBINARY(16),
  28425.     @agenttype NVARCHAR(20) 
  28426.     ) AS
  28427.     SET NOCOUNT ON
  28428.     
  28429.     /*
  28430.     ** Declarations
  28431.     */
  28432.     
  28433.     DECLARE @paramstart    INT
  28434.     DECLARE @paramend      INT
  28435.     DECLARE @paramlen      INT
  28436.     DECLARE @paramend2     INT
  28437.     DECLARE @command       NVARCHAR(3200) 
  28438.     DECLARE @commandtail   NVARCHAR(3200)
  28439.     DECLARE @pattern       NVARCHAR(100)
  28440.  
  28441.     SELECT @pattern = N'%-[Oo][Ff][Ff][Ll][Oo][Aa][Dd]%'
  28442.     SELECT @paramlen = LEN(N'-offload')
  28443.     SELECT @command = NULL
  28444.  
  28445.     -- use the job_id and the agent type to retrieve the agent command
  28446.     -- line, only one agent command step is allowed in a job
  28447.  
  28448.     SELECT @command = command FROM msdb.dbo.sysjobsteps 
  28449.      WHERE job_id = @job_id AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)
  28450.  
  28451.     -- purge all instances of '-offload servername' from the agent command line
  28452.     SELECT @paramstart = PATINDEX(@pattern, @command)
  28453.     WHILE ((@command IS NOT NULL) AND (@paramstart <> 0))
  28454.     BEGIN       
  28455.         -- extract the part of the command line after the -Offload parameter
  28456.         SELECT @commandtail = SUBSTRING(@command, @paramstart + @paramlen, 
  28457.                                         LEN(@command) - 
  28458.                                         (@paramstart + @paramlen) + 1)
  28459.  
  28460.         -- search for the beginning of the server name that follows -offload
  28461.         -- in the command tail; note that the empty spaces in the square
  28462.         -- bracket of the pattern are actually a space and a tab
  28463.  
  28464.         SELECT @paramend = PATINDEX(N'%[^     ]%', @commandtail)
  28465.  
  28466.         -- search for the end of the server name that follows -offload
  28467.         IF (@paramend <> 0) 
  28468.         BEGIN
  28469.             SELECT @commandtail = SUBSTRING(@commandtail, @paramend, 
  28470.                                             LEN(@commandtail) - @paramend + 1)
  28471.             SELECT @paramend2 = PATINDEX(N'%[     ]%', @commandtail) 
  28472.             IF (@paramend2 <> 0)
  28473.             BEGIN
  28474.                 SELECT @paramend = @paramend + @paramend2 - 1
  28475.             END
  28476.             ELSE
  28477.             BEGIN
  28478.                 -- reaching the end of the command line
  28479.                 SELECT @paramend = @paramend + LEN(@commandtail) - 1
  28480.                 IF @paramstart > 1 
  28481.                 BEGIN
  28482.                     SELECT @paramstart = @paramstart - 1
  28483.                     SELECT @paramend = @paramend + 1
  28484.                 END
  28485.             END
  28486.         
  28487.         END                
  28488.         -- Remove the -Offload parameter from the command line
  28489.         SELECT @command = STUFF(@command, @paramstart, @paramlen + @paramend, N'')
  28490.  
  28491.         SELECT @paramstart = PATINDEX(@pattern, @command)
  28492.     END
  28493.     
  28494.     -- update the agent command line with all the -offload's removed
  28495.     UPDATE msdb.dbo.sysjobsteps 
  28496.        SET command = @command
  28497.      WHERE job_id = @job_id AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)   
  28498.     
  28499.     RETURN 0
  28500. GO
  28501. EXEC dbo.sp_MS_marksystemobject sp_MSremoveoffloadparameter
  28502. GO
  28503.  
  28504. -- No parameter checking is performed in sp_MSaddoffloadparameter 
  28505. raiserror(15339,-1,-1,'sp_MSaddoffloadparameter')
  28506. GO
  28507. CREATE PROCEDURE sp_MSaddoffloadparameter (
  28508.     @offloadserver sysname, /* Name of the target server to offload the agent to */
  28509.     @job_id        VARBINARY(16), 
  28510.     @agenttype     NVARCHAR(20) /* Agent type can either be 'merge' or 'distribution' */
  28511.     ) AS
  28512.     
  28513.     SET NOCOUNT ON
  28514.  
  28515.     /*
  28516.     **  Declarations
  28517.     */
  28518.  
  28519.     DECLARE @command               NVARCHAR(3200)
  28520.     
  28521.     -- initialize variables
  28522.     SELECT @command = NULL    
  28523.  
  28524.     -- call sp_MSremoveoffloadparameter to remove all exisiting instances of the 
  28525.     -- -offload parameters from the agent command line; the return status
  28526.     -- of sp_MSremoveoffloadparameter is ignored
  28527.     EXEC sp_MSremoveoffloadparameter @job_id=@job_id, @agenttype=@agenttype
  28528.     
  28529.     -- update the agent command line by appending '-Offload ' + 
  28530.     -- @offloadserver    
  28531.     
  28532.     UPDATE msdb.dbo.sysjobsteps
  28533.        SET command = command + N' -Offload ' + @offloadserver 
  28534.      WHERE job_id = @job_id 
  28535.        AND LOWER(subsystem collate SQL_Latin1_General_CP1_CS_AS) = LOWER(@agenttype collate SQL_Latin1_General_CP1_CS_AS)
  28536.          
  28537.     RETURN 0
  28538. GO
  28539. EXEC dbo.sp_MS_marksystemobject sp_MSaddoffloadparameter
  28540. GO
  28541.  
  28542. --
  28543. --  System UDF fn_MSgensqescstr
  28544. --     This function takes as input a varchar
  28545. --    and stuffs an extra single quote for any single quotes in the string
  28546. --
  28547. raiserror(15339,-1,-1,'fn_MSgensqescstr')
  28548. go
  28549. create function dbo.fn_MSgensqescstr (
  28550.     @pstrin nvarchar(4000) )
  28551. returns nvarchar(4000)
  28552. as
  28553. begin
  28554.     declare @pstrout nvarchar(4000)
  28555.  
  28556.     select @pstrout = REPLACE(@pstrin, N'''', N'''''')
  28557.     return @pstrout
  28558. end
  28559. go
  28560.  
  28561. raiserror(15339,-1,-1,'sp_MSUpgradeConflictTable')
  28562. GO
  28563. create proc sp_MSUpgradeConflictTable
  28564.     @skip_procgen bit = 0
  28565. AS
  28566. declare @retcode int
  28567. declare @conflict_table sysname
  28568. declare @pubid uniqueidentifier 
  28569. declare @artid uniqueidentifier 
  28570. declare @ins_conflict_proc sysname
  28571. declare @conflict_id    int
  28572. declare @objid            int
  28573. declare @qual_conflict    nvarchar(132)
  28574.  
  28575.  
  28576. if exists( select * from sysobjects where name = 'MSmerge_delete_conflicts' ) and 
  28577.     not exists (select * from syscolumns where id = object_id('MSmerge_delete_conflicts') and name = 'create_time')
  28578. begin
  28579.     alter table MSmerge_delete_conflicts add create_time datetime not null default getdate()
  28580. end
  28581.  
  28582. declare AC CURSOR LOCAL FAST_FORWARD for select conflict_table, objid, ins_conflict_proc, pubid, artid from sysmergearticles 
  28583. open AC
  28584. fetch AC into @conflict_table, @objid, @ins_conflict_proc, @pubid, @artid
  28585. while (@@fetch_status<>-1)
  28586. begin
  28587.     if @conflict_table is NOT null
  28588.     begin
  28589.         select @conflict_id = object_id(@conflict_table)
  28590.         select @qual_conflict=QUOTENAME(@conflict_table)
  28591.         /*
  28592.         ** Upgrade conflict table so that it can get cleaned up later on
  28593.         */
  28594.         if @conflict_id is not NULL and not exists (select name from syscolumns where name='MSrepl_create_time' and id=@conflict_id)
  28595.         begin
  28596.             exec ('alter table ' + @qual_conflict + ' add MSrepl_create_time datetime not null default getdate() ')
  28597.             if @@ERROR<>0
  28598.             begin
  28599.                 close AC
  28600.                 deallocate AC
  28601.                 return (1)
  28602.             end
  28603.             /*
  28604.             ** use create_time value for the new column before dropping create_time column, after making 
  28605.             ** sure create_time is not from user table.
  28606.             */
  28607.             if exists (select name from syscolumns where name='create_time' and id=@conflict_id) and
  28608.                 not exists (select name from syscolumns where name='create_time' and id=@objid) 
  28609.             begin
  28610.                 exec ('update ' + @qual_conflict + ' set MSrepl_create_time=create_time')
  28611.                 if @@ERROR<>0
  28612.                 begin
  28613.                     close AC
  28614.                     deallocate AC
  28615.                     return (1)
  28616.                 end
  28617.                 declare @colid                     int
  28618.                 declare @default_constraint        sysname
  28619.                 
  28620.                 select @colid = colid from syscolumns where name='create_time' and id=@conflict_id
  28621.                 select @default_constraint=object_name(constid) from sysconstraints where id=@conflict_id and colid=@colid
  28622.                 /*
  28623.                 ** drop default constrait on create_time column
  28624.                 */
  28625.                 if @default_constraint is not NULL
  28626.                 begin
  28627.                     exec ('alter table ' + @qual_conflict + ' drop constraint ' + @default_constraint)
  28628.                     if @@ERROR<>0
  28629.                     begin
  28630.                         close AC
  28631.                         deallocate AC
  28632.                         return (1)
  28633.                     end
  28634.                 end
  28635.                 
  28636.                 exec ('alter table ' + @qual_conflict + ' drop column create_time')
  28637.                 if @@ERROR<>0
  28638.                 begin
  28639.                     close AC
  28640.                     deallocate AC
  28641.                     return (1)
  28642.                 end
  28643.             end
  28644.             if @ins_conflict_proc is not NULL and object_id(@ins_conflict_proc) is not NULL 
  28645.             begin
  28646.                 exec ('drop procedure ' + @ins_conflict_proc)
  28647.                 if @@ERROR<>0
  28648.                 begin
  28649.                     close AC
  28650.                     deallocate AC            
  28651.                     return (1)
  28652.                 end
  28653.                 --force to regenerate conflict insert proc to pick up the new column name
  28654.                 update sysmergearticles set ins_conflict_proc=NULL where artid=@artid and pubid=@pubid
  28655.                 if @@ERROR<>0
  28656.                 begin
  28657.                     close AC
  28658.                     deallocate AC            
  28659.                     return (1)
  28660.                 end
  28661.  
  28662.                 -- Do not upgrade conflict tables if this is called from sp_restoredbreplication, as 
  28663.                 -- the entire replication will be striped out.
  28664.                 if @skip_procgen = 0
  28665.                 begin
  28666.                     exec @retcode = sp_MSgetconflictinsertproc @artid, @pubid, 0     
  28667.                     if @@ERROR<>0 or @retcode<>0
  28668.                     begin
  28669.                         close AC
  28670.                         deallocate AC            
  28671.                         return (1)
  28672.                     end
  28673.                 end
  28674.             end
  28675.         end
  28676.  
  28677.         if not exists (select * from sysindexes where id = @conflict_id and keys is not null)
  28678.         begin
  28679.             declare @rgcol sysname
  28680.             declare @indname sysname
  28681.             declare @quotedname sysname
  28682.             declare @owner sysname
  28683.             
  28684.             select @owner=user_name(uid) from sysobjects where id = @objid
  28685.             select @rgcol = QUOTENAME(name) from syscolumns where id = @objid and
  28686.                     ColumnProperty(id, name, 'isrowguidcol') = 1
  28687.             select @indname = 'uc_' + @conflict_table
  28688.             set @indname = QUOTENAME(@indname)
  28689.             set @quotedname = QUOTENAME(@owner) + '.' + QUOTENAME(@conflict_table)
  28690.             exec ('Create unique clustered index ' + @indname + ' on ' + @quotedname +
  28691.                 ' (' + @rgcol + ', origin_datasource)' )
  28692.             if @@ERROR <> 0
  28693.             begin
  28694.                 close AC
  28695.                 deallocate AC            
  28696.                 return (1)
  28697.             end
  28698.         end
  28699.     end
  28700.     fetch next from AC into @conflict_table, @objid, @ins_conflict_proc, @pubid, @artid
  28701. end
  28702. close AC
  28703. deallocate AC
  28704. return (0)
  28705. GO
  28706. exec dbo.sp_MS_marksystemobject sp_MSUpgradeConflictTable
  28707. Go
  28708.  
  28709. --
  28710. -- This SP is used by the queued tran triggers to insert data into the SQL queue
  28711. -- it enforces the security check and does the insert into the queue table
  28712. --
  28713. raiserror(15339,-1,-1,'sp_MSsendtosqlqueue')
  28714. GO
  28715. create proc sp_MSsendtosqlqueue (
  28716.     @objid int
  28717.     ,@publisher sysname
  28718.     ,@publisher_db sysname
  28719.     ,@publication sysname
  28720.     ,@owner sysname
  28721.     ,@tranid sysname
  28722.     ,@data varbinary(8000)
  28723.     ,@datalen int
  28724.     ,@commandtype int = 1
  28725.     ,@cmdstate bit = 0
  28726. )
  28727. as
  28728. begin
  28729.     set nocount on
  28730.  
  28731.     --
  28732.     -- Security check
  28733.     -- Make sure this proc is infact being called from the given object(trigger)
  28734.     -- 
  28735.     if (trigger_nestlevel(@objid) = 0)
  28736.     begin
  28737.         raiserror(14126, 16, 2)
  28738.         return 1
  28739.     end
  28740.     
  28741.     --
  28742.     -- Security check: the caller of this SP has to be one of the 
  28743.     -- predefined replication objects for this subscription
  28744.     --
  28745.     if (@objid not in (select object_id(quotename(@owner) + N'.' + quotename([object_name])) 
  28746.         from dbo.MSreplication_objects
  28747.         where publisher = @publisher and publisher_db = @publisher_db and
  28748.                 publication = @publication and object_type = 'T'))
  28749.     begin
  28750.         raiserror(14126, 16, 3)
  28751.         return 1
  28752.     end
  28753.  
  28754.     --
  28755.     -- insert into the queue table
  28756.     --
  28757.     insert into dbo.MSreplication_queue (publisher,publisher_db,publication,tranid,data,datalen,commandtype,cmdstate)
  28758.         values(@publisher,@publisher_db,@publication,@tranid,@data,@datalen,@commandtype,@cmdstate)
  28759.  
  28760.     --
  28761.     -- all done
  28762.     --
  28763.     return 0
  28764. end
  28765. go
  28766. exec dbo.sp_MS_marksystemobject sp_MSsendtosqlqueue
  28767. go            
  28768.  
  28769. /*
  28770. ** One and only one of these two parameters needs to be specified - meaning adjust publisher side
  28771. ** identity range at publication level (all tables) or table level (whose name is given)
  28772. */
  28773.  
  28774. raiserror(15339,-1,-1,'sp_adjustpublisheridentityrange')
  28775. GO
  28776. create procedure sp_adjustpublisheridentityrange (
  28777.     @publication    sysname = NULL,
  28778.     @table_name         sysname = NULL,
  28779.     @table_owner    sysname = NULL
  28780. )
  28781. AS
  28782. set nocount on
  28783.  
  28784. declare @retcode                 int, @object_found bit
  28785. declare @objid                    int
  28786. declare @qualified_table_name    nvarchar(260)
  28787. declare @identity_support        int
  28788. declare @pubid                    uniqueidentifier
  28789.  
  28790. select @object_found = 0
  28791.  
  28792. /*
  28793. ** Security Check
  28794. */
  28795. EXEC @retcode = dbo.sp_MSreplcheck_publish
  28796. IF @@ERROR <> 0 or @retcode <> 0
  28797.     return (1)
  28798.  
  28799. if ((@publication is NULL and @table_name is NULL) or 
  28800.         (@publication is NULL and @table_name is NULL) or
  28801.         (@publication is not NULL and @table_name is not NULL))
  28802. begin
  28803.     raiserror(21314, 16, -1, '@publication', '@table_name')
  28804.     return (1)
  28805. end
  28806.  
  28807. if @publication is NULL
  28808. begin
  28809.     if @table_owner is NULL
  28810.         select @table_owner = user_name()
  28811.     select @qualified_table_name = QUOTENAME(@table_owner) + '.' + QUOTENAME(@table_name)
  28812.     
  28813.     select @objid = object_id(@qualified_table_name)
  28814.     if @objid is NULL
  28815.     begin 
  28816.         RAISERROR (14027, 11, -1, @qualified_table_name)
  28817.         return (1)
  28818.     end
  28819. end
  28820.  
  28821. --Do this for merge?
  28822. if exists (select * from sysobjects where name = 'sysmergepublications')
  28823. begin
  28824.     if @publication is NULL
  28825.     begin
  28826.         select @identity_support = identity_support from sysmergearticles where objid=@objid
  28827.         if @identity_support is not null
  28828.         begin
  28829.             select @object_found = 1
  28830.             if @identity_support = 0
  28831.                 return (0)
  28832.             exec @retcode = sp_MSadjustmergeidentity @tablename=@table_name    
  28833.             if @retcode<>0 or @@ERROR<>0
  28834.             begin
  28835.                 raiserror(21315, 16, -1, @table_name)
  28836.                 return (1)
  28837.             end
  28838.         end
  28839.     end
  28840.  
  28841.     if @table_name is NULL
  28842.     begin
  28843.         select @pubid=pubid FROM sysmergepublications
  28844.             WHERE name = @publication and UPPER(publisher)=UPPER(@@servername) and publisher_db=db_name()
  28845.         if @pubid is not null
  28846.         begin
  28847.             select @object_found = 1
  28848.             if not exists (select * from sysmergearticles where pubid=@pubid and identity_support=1)
  28849.                 return (0)
  28850.             exec @retcode = sp_MSadjustmergeidentity @publication=@publication
  28851.             if @retcode<>0 or @@ERROR<>0
  28852.             begin
  28853.                 raiserror(21316, 16, -1, @publication)
  28854.                 return (1)
  28855.             end    
  28856.         end    
  28857.     end
  28858. end
  28859.  
  28860. if exists (select * from sysobjects where name = 'syspublications')
  28861. begin
  28862.     if @publication is NULL
  28863.     begin
  28864.         declare @artid int
  28865.         select top 1 @artid = artid from sysarticles where 
  28866.             objid = @objid
  28867.         if @artid is not null
  28868.         begin
  28869.             select @object_found = 1
  28870.             exec @retcode = sp_MSpub_adjust_identity @artid
  28871.             if @retcode<>0 or @@ERROR<>0
  28872.                 return (1)
  28873.         end
  28874.     end
  28875.     else
  28876.     begin
  28877.         declare @publication_id int
  28878.         select @publication_id = pubid from syspublications where name = @publication
  28879.         if @publication_id is not null
  28880.         begin
  28881.             select @object_found = 1
  28882.             DECLARE adjust_identity CURSOR LOCAL FAST_FORWARD FOR
  28883.                 SELECT art1.objid
  28884.                   FROM sysarticles art1,
  28885.                        sysarticleupdates art2
  28886.                   where art1.pubid = @publication_id and
  28887.                         art1.artid = art2.artid and
  28888.                         art2.identity_support = 1 and
  28889.                         (art1.artid = @artid or @artid is null)
  28890.             FOR READ ONLY
  28891.  
  28892.             OPEN adjust_identity        
  28893.             FETCH adjust_identity INTO @objid
  28894.             WHILE (@@fetch_status <> -1)
  28895.             begin
  28896.                 exec @retcode = sp_MSpub_adjust_identity @artid
  28897.                 if @retcode<>0 or @@ERROR<>0
  28898.                     return (1)
  28899.                 FETCH adjust_identity INTO @objid
  28900.             end
  28901.         end
  28902.     end
  28903. end
  28904. if @object_found = 0
  28905. begin
  28906.     if @publication is null
  28907.         raiserror(21246, 16, -1, @qualified_table_name)
  28908.     else
  28909.         RAISERROR (20026, 11, -1, @publication)
  28910. end
  28911.  
  28912. RETURN (0)
  28913. GO
  28914. exec dbo.sp_MS_marksystemobject sp_adjustpublisheridentityrange
  28915. GO            
  28916.  
  28917. grant execute on dbo.sp_adjustpublisheridentityrange to public
  28918. GO
  28919.  
  28920. -- sp_MSestimate(merge)snapshotworkload is called exclusively by the 
  28921. -- snapshot agent to estimate the amount of work that has to be done for
  28922. -- a snapshot session and a breakdown of the work load into subtasks
  28923.  
  28924. raiserror(15339,-1,-1,'sp_MSestimatemergesnapshotworkload')
  28925. GO
  28926. create proc sp_MSestimatemergesnapshotworkload (
  28927.     @publication sysname
  28928.     )
  28929. as
  28930. begin
  28931.     set nocount on
  28932.  
  28933.     declare @taskload                       int
  28934.     declare @bigtaskload                    bigint
  28935.     declare @table_created                  bit
  28936.     declare @retcode                        int
  28937.  
  28938.     -- constant
  28939.     declare @zerouuid                       uniqueidentifier
  28940.     select @zerouuid = convert(uniqueidentifier, N'{00000000-0000-0000-0000-000000000000}')
  28941.     -- Publication info
  28942.     declare @pubid                          uniqueidentifier
  28943.     declare @compress_snapshot              bit
  28944.     declare @snapshot_in_defaultfolder      bit
  28945.     declare @alt_snapshot_folder            nvarchar(255)
  28946.     declare @enabled_for_internet           bit
  28947.     declare @ftp_password                   nvarchar(524) 
  28948.     declare @ftp_subdirectory               nvarchar(255)
  28949.     declare @pre_snapshot_script            nvarchar(255)
  28950.     declare @post_snapshot_script           nvarchar(255)    
  28951.     declare @dynamic_filters                bit
  28952.  
  28953.     -- Per publication summary stats
  28954.     declare @numarticles                    int
  28955.     declare @totalrowcount                  int   
  28956.     declare @needsysprescript               bit
  28957.     declare @copysnapshot                   bit
  28958.     declare @deletefiles                    bit
  28959.     declare @scriptproccost                 int
  28960.     declare @addcommandstotal               int
  28961.     declare @numscripts                     int
  28962.     declare @totalbcpcostper100             int
  28963.     declare @numprescriptcommands           int 
  28964.     declare @numunsyncedarticles            int
  28965.     declare @numtablearticles               int
  28966.     declare @systablesrowcount              int
  28967.     declare @maxint                         int
  28968.  
  28969.     select @numarticles = 0
  28970.     select @totalrowcount = 0
  28971.     select @needsysprescript = 0
  28972.     select @copysnapshot = 0
  28973.     select @deletefiles = 0
  28974.     select @scriptproccost = 0
  28975.     select @deletefiles = 0
  28976.     select @addcommandstotal = 0
  28977.     select @numscripts = 0
  28978.     select @totalbcpcostper100 = 0
  28979.     select @numprescriptcommands = 0
  28980.     select @numunsyncedarticles = 0
  28981.     select @numtablearticles = 0
  28982.     select @systablesrowcount = 0
  28983.     select @maxint = 2147483647
  28984.  
  28985.     -- Per article variables
  28986.     declare @artid                          uniqueidentifier
  28987.     declare @schema_option                  int
  28988.     declare @creation_script                nvarchar(255)
  28989.     declare @type                           tinyint
  28990.     declare @objid                          int
  28991.     declare @rowcount                       int
  28992.     declare @name                           sysname
  28993.     declare @status                         int
  28994.  
  28995.  
  28996.     -- Security check
  28997.     select @retcode = 0
  28998.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  28999.     IF @@ERROR <> 0 or @retcode <> 0
  29000.         return (1)
  29001.  
  29002.     select @table_created = 0
  29003.  
  29004.     select @pubid = null
  29005.     select @compress_snapshot = 0
  29006.     select @snapshot_in_defaultfolder = 0
  29007.     select @alt_snapshot_folder = null
  29008.     select @enabled_for_internet = 0
  29009.     select @ftp_password = null
  29010.     select @ftp_subdirectory = null
  29011.     select @pre_snapshot_script = null
  29012.     select @post_snapshot_script = null
  29013.     -- Validate publication and retrieve publication information 
  29014.     select @pubid = pubid, 
  29015.            @compress_snapshot = compress_snapshot,
  29016.            @snapshot_in_defaultfolder = snapshot_in_defaultfolder,
  29017.            @alt_snapshot_folder = alt_snapshot_folder,
  29018.            @enabled_for_internet = enabled_for_internet,
  29019.            @ftp_password = ftp_password,
  29020.            @ftp_subdirectory = ftp_subdirectory,
  29021.            @pre_snapshot_script = pre_snapshot_script,
  29022.            @post_snapshot_script = post_snapshot_script,
  29023.            @dynamic_filters = dynamic_filters
  29024.            from sysmergepublications
  29025.      where name = @publication
  29026.        and upper(@@servername) = publisher
  29027.        and publisher_db = db_name()
  29028.     if @pubid = null
  29029.     begin   
  29030.         raiserror(20026, 11, -1, @publication)
  29031.         return (1)
  29032.     end
  29033.  
  29034.     -- An artid of -1 means the task is a per publication
  29035.     -- task
  29036.  
  29037.     -- Task id mapping - This is the list of task whose completion can be 
  29038.     -- reported by the snapshot agent
  29039.     -- 0 - Total workload (not really a task)
  29040.     -- 1 - Schema script generation
  29041.     -- 2 - Trigger script generation 
  29042.     -- 3 - XProp script generation
  29043.     -- 4 - Bcp file generation
  29044.     -- 5 - Activating subscription (estimate number of subscriptions?)
  29045.     -- 6 - Adding snapshot commands
  29046.     -- 7 - System pre-script generation
  29047.     -- 8 - Flushing folder for scripts
  29048.     -- 9 - Constraint script generation
  29049.     -- 10 - Copying pre-script
  29050.     -- 11 - Copying post-script
  29051.     -- 12 - Copying custom schema creation script
  29052.     -- 13 - Index script generation
  29053.     -- 14 - Flushing the cabinet
  29054.     -- 15 - Adding rowguid column
  29055.     -- 16 - Setting article procs
  29056.     -- 17 - Adding merge triggers
  29057.     -- 18 - Generating system table scripts
  29058.     -- 19 - Generating system table bcp files
  29059.     -- 20 - Making publication generation
  29060.     -- 21 - Generating and setting conflict script
  29061.     -- 22 - Generating publication views
  29062.     
  29063.     -- Weights and overheads
  29064.     -- DMO Script generation - 7/script
  29065.     -- BCP 5 overhead + 5/100 rows
  29066.     -- Flush folder for bcp 2/100 rows
  29067.     -- Delete file 2
  29068.     -- System pre-snapshot script 1 overhead + 0.5/pre-creation command
  29069.     -- Copying user file 2
  29070.     -- Adding file to cabinet 1 for scripts and 1/100 rows in bcp file
  29071.     -- Loading article info 3
  29072.     -- Delete bcp file 2/100rows 
  29073.     -- Copy bcp file  2/100rows  
  29074.     -- Flush scripts folder 1/2 scripts
  29075.     -- Flushing cabinet per 5 scripts 1
  29076.     -- Flushing cabinet per 500 rows 1
  29077.     -- Script execution 3
  29078.     -- Adding rowguid columns 20/100 rows
  29079.     -- Adding merge triggers 7
  29080.     -- Setting article procs 5
  29081.  
  29082.     -- Here is the list of cost factors 
  29083.     declare @addcommandcost     int
  29084.     declare @dmoscriptcost      int
  29085.     declare @bcpoverhead        int
  29086.     declare @bcpcostper100      int
  29087.     declare @flushper100        int
  29088.     declare @flushperscript     int
  29089.     declare @delfilecost        int
  29090.     declare @syspreoverhead     int
  29091.     declare @syspreper2commands int
  29092.     declare @addbcptocabper100  int
  29093.     declare @addscripttocab     int
  29094.     declare @copyfilecost       int
  29095.     declare @loadartinfo        int    
  29096.     declare @deletebcpper100    int
  29097.     declare @copybcpper100      int
  29098.     declare @flushper2scripts   int
  29099.     declare @flushcabper5scripts int
  29100.     declare @flushcabper500bcprows int
  29101.     declare @scriptexeccost int
  29102.     declare @rowguidper100 int
  29103.     declare @addmergetriggers int
  29104.     declare @setartprocs int
  29105.     declare @pubviewperarticle int
  29106.     declare @genperarticle int
  29107.  
  29108.     select @addcommandcost = 2
  29109.     select @dmoscriptcost = 7
  29110.     select @bcpcostper100 = 20
  29111.     select @bcpoverhead = 2
  29112.     select @flushper100 = 2
  29113.     select @flushperscript = 3
  29114.     select @delfilecost = 2
  29115.     select @syspreoverhead = 1
  29116.     select @syspreper2commands = 1
  29117.     select @addbcptocabper100 = 1
  29118.     select @addscripttocab = 1
  29119.     select @copyfilecost = 2
  29120.     select @loadartinfo = 3    
  29121.     select @deletebcpper100 = 1
  29122.     select @copybcpper100 = 2
  29123.     select @flushper2scripts = 1
  29124.     select @flushcabper5scripts = 1
  29125.     select @flushcabper500bcprows = 1
  29126.     select @scriptexeccost = 3
  29127.     select @rowguidper100 = 20
  29128.     select @addmergetriggers = 3
  29129.     select @pubviewperarticle = 2
  29130.     select @genperarticle = 2
  29131.     select @setartprocs = 5
  29132.  
  29133.     create table #workload_breakdown
  29134.     (
  29135.         name        sysname collate database_default,
  29136.         artid       uniqueidentifier,
  29137.         taskid      int,
  29138.         taskload    int
  29139.     )
  29140.     if @@error <> 0
  29141.         goto Failure
  29142.  
  29143.     select @table_created = 1
  29144.  
  29145.     -- Per publication work load estimate that can be done using publication
  29146.     -- properties alone
  29147.     
  29148.     -- Adding snapshot header commands
  29149.     
  29150.     -- Snapshot header begins + Snapshot header ends +
  29151.     -- directory command + Snapshot trailer command = 3 * @addcommandcost
  29152.     select @addcommandstotal = 4
  29153.     
  29154.     -- Alternate snapshot folder = 1 * @addcommandcost
  29155.     if @alt_snapshot_folder is not null and
  29156.        @alt_snapshot_folder <> N'' and
  29157.        @snapshot_in_defaultfolder = 1
  29158.     begin
  29159.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29160.     end
  29161.  
  29162.     -- Ftp commands
  29163.     if @enabled_for_internet = 1
  29164.     begin
  29165.         -- ftp_address and ftp_port must be there +=2 * @addcommandcost
  29166.         select @addcommandstotal = @addcommandstotal + 2 * @addcommandcost
  29167.  
  29168.         -- ftp_password += 1 * @addcommandcost
  29169.         if @ftp_password is not null and
  29170.            @ftp_password <> N''
  29171.         begin
  29172.             select @addcommandstotal = @addcommandstotal + @addcommandcost
  29173.         end
  29174.         
  29175.         -- ftp_subdirectory += 1 * @addcommandcost
  29176.         if @ftp_subdirectory is not null and
  29177.            @ftp_subdirectory <> N''
  29178.         begin
  29179.             select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  29180.         end
  29181.     end
  29182.  
  29183.     -- Compressed archive path
  29184.     if @compress_snapshot = 1
  29185.     begin
  29186.         select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  29187.     end    
  29188.  
  29189.     -- Snapshot trailer command
  29190.     select @addcommandstotal = @addcommandstotal +  @addcommandcost
  29191.  
  29192.     -- Need to copy files?
  29193.     if @alt_snapshot_folder is not null and @alt_snapshot_folder <> N''
  29194.        and @snapshot_in_defaultfolder = 1 and @compress_snapshot = 0
  29195.     begin
  29196.         select @copysnapshot = 1
  29197.     end
  29198.  
  29199.     -- Compute per-script file post processing cost and bcp cost per 100 rows
  29200.     -- Need to delete files?
  29201.     if (@alt_snapshot_folder is null or @alt_snapshot_folder <> N''
  29202.        or @snapshot_in_defaultfolder = 0) and @compress_snapshot = 1
  29203.     begin
  29204.         select @deletefiles = 1
  29205.     end
  29206.  
  29207.     select @totalbcpcostper100 = @bcpcostper100
  29208.     -- Copy file?
  29209.     if @copysnapshot = 1
  29210.     begin
  29211.         select @scriptproccost = @scriptproccost + @copyfilecost
  29212.         select @totalbcpcostper100 = @totalbcpcostper100 + @copybcpper100
  29213.     end
  29214.  
  29215.     -- Add file to cabinet?
  29216.     if @compress_snapshot = 1
  29217.     begin
  29218.         select @scriptproccost = @scriptproccost + @addscripttocab 
  29219.         select @totalbcpcostper100 = @totalbcpcostper100 + @addbcptocabper100
  29220.     end
  29221.  
  29222.     -- Delete file?
  29223.     if @deletefiles = 1
  29224.     begin 
  29225.         select @scriptproccost = @scriptproccost + @delfilecost
  29226.         select @totalbcpcostper100 = @totalbcpcostper100 + @deletebcpper100
  29227.     end
  29228.  
  29229.     -- Pre/Post-snapshot scripts, has to be computed after the 
  29230.     -- the per-script post-processing cost is calculated 
  29231.     if @pre_snapshot_script is not null and
  29232.        @pre_snapshot_script <> N''
  29233.     begin
  29234.         -- Cost of copying the script file
  29235.         select @taskload = @copyfilecost + @scriptproccost
  29236.         insert #workload_breakdown values (N'', @zerouuid, 10, @taskload)
  29237.         -- Cost of adding the pre-snapshot command
  29238.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29239.         -- Increment scripts counter
  29240.         select @numscripts = @numscripts + 1
  29241.     end
  29242.  
  29243.     if @post_snapshot_script is not null and
  29244.        @post_snapshot_script <> N''
  29245.     begin
  29246.         -- Cost of copying the script file
  29247.         select @taskload = @copyfilecost + @scriptproccost
  29248.         insert #workload_breakdown values (N'', @zerouuid, 11, @taskload)
  29249.         -- Cost of adding the post-snapshot command
  29250.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29251.         -- Increment scripts counter
  29252.         select @numscripts = @numscripts + 1
  29253.     end
  29254.            
  29255.     -- Estimate the break down of per article tasks 
  29256.     declare hCarticles cursor local fast_forward
  29257.     for select artid, creation_script, objid, convert(int, schema_option), type, name,
  29258.                status  
  29259.           from sysmergeextendedarticlesview where pubid = @pubid 
  29260.  
  29261.     open hCarticles
  29262.    
  29263.     fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name,
  29264.         @status
  29265.     while (@@fetch_status <> -1)
  29266.     begin
  29267.         if @type = 0x40 -- Schema view articles, may require index scripting
  29268.         begin
  29269.             select @taskload = 0
  29270.             -- See if a custom creation script will be used 
  29271.             if @schema_option = 0 and @creation_script is not null and
  29272.                @creation_script <> N''
  29273.             begin
  29274.                 -- Script generation
  29275.                 select @taskload = @copyfilecost + @scriptproccost
  29276.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  29277.                 -- Cost of adding commands for the custom script
  29278.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29279.                 -- Increment scripts counter
  29280.                 select @numscripts = @numscripts + 1
  29281.                 -- No need to worry about index script
  29282.             end
  29283.             else
  29284.             begin
  29285.                 -- Script generation 
  29286.                 select @taskload = @dmoscriptcost + @scriptproccost
  29287.                 -- Must script out schema script
  29288.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  29289.                 -- Cost of adding the command
  29290.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29291.                 -- Increment scripts counter
  29292.                 select @numscripts = @numscripts + 1
  29293.  
  29294.                 -- DRI script containing the view's indexes?
  29295.                 if (@schema_option & 0x50) <> 0x0
  29296.                 begin
  29297.                     -- Cost of script generation
  29298.                     select @taskload = @dmoscriptcost + @scriptproccost
  29299.                     insert #workload_breakdown values (@name, @artid, 9, @taskload)
  29300.                     -- Cost of adding command for the script
  29301.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29302.                     -- Increment scripts counter
  29303.                     select @numscripts = @numscripts + 1
  29304.                 end
  29305.  
  29306.                 -- Trigger script?
  29307.                 if (@schema_option & 0x100) <> 0x0
  29308.                 begin
  29309.                     -- Cost of script generation
  29310.                     select @taskload = @dmoscriptcost + @scriptproccost
  29311.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  29312.                     -- Cost of adding command for the script
  29313.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29314.                     -- Increment scripts counter
  29315.                     select @numscripts = @numscripts + 1
  29316.                 end 
  29317.  
  29318.                 -- XProp script?
  29319.                 if (@schema_option & 0x2000) <> 0x0
  29320.                 begin
  29321.                     -- Cost of script generation 
  29322.                     select @taskload = @dmoscriptcost + @scriptproccost
  29323.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  29324.                     -- Cost of adding command
  29325.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29326.                     -- Increment scripts counter
  29327.                     select @numscripts = @numscripts + 1
  29328.                 end
  29329.             end        
  29330.         end
  29331.         else if @type in (0x08, 0x18, 0x20, 0x80) -- Regular schema articles 
  29332.         begin
  29333.             select @taskload = 0
  29334.             -- See if a custom creation script will be used 
  29335.             if @schema_option = 0 and @creation_script is not null and
  29336.                @creation_script <> N''
  29337.             begin
  29338.                 -- Script generation
  29339.                 select @taskload = @copyfilecost + @scriptproccost
  29340.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  29341.                 -- Cost of adding commands for the custom script
  29342.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29343.                 -- Increment scripts counter
  29344.                 select @numscripts = @numscripts + 1
  29345.             end
  29346.             else 
  29347.             begin
  29348.                 -- Script generation 
  29349.                 select @taskload = @dmoscriptcost + @scriptproccost
  29350.                 -- Must script out schema script
  29351.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  29352.                 -- Cost of adding the command
  29353.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29354.                 -- Increment scripts counter
  29355.                 select @numscripts = @numscripts + 1
  29356.  
  29357.                 -- XProp script?
  29358.                 if (@schema_option & 0x2000) <> 0x0
  29359.                 begin
  29360.                     -- Cost of script generation 
  29361.                     select @taskload = @dmoscriptcost + @scriptproccost
  29362.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  29363.                     -- Cost of adding command
  29364.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29365.                 -- Increment scripts counter
  29366.                 select @numscripts = @numscripts + 1
  29367.                 end
  29368.             end
  29369.         end
  29370.         else -- Merge table articles, requires bcp
  29371.         begin
  29372.            select @taskload = 0
  29373.            -- See if a custom creation script will be used 
  29374.             if @schema_option = 0 and @creation_script is not null and
  29375.                @creation_script <> N''
  29376.             begin
  29377.                 -- Script generation
  29378.                 select @taskload = @copyfilecost + @scriptproccost
  29379.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  29380.                 -- Cost of adding commands for the custom script
  29381.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29382.                 -- Increment scripts counter
  29383.                 select @numscripts = @numscripts + 1
  29384.                 -- No need to worry about index script
  29385.             end
  29386.             else
  29387.             begin
  29388.                 -- Script generation 
  29389.                 select @taskload = @dmoscriptcost + @scriptproccost
  29390.                 -- Must script out schema script
  29391.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  29392.                 -- Cost of adding the command
  29393.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29394.                 -- Increment scripts counter
  29395.                 select @numscripts = @numscripts + 1
  29396.  
  29397.                 -- Constraint script is not optional for merge table article
  29398.                 -- Cost of script generation
  29399.                 select @taskload = @dmoscriptcost + @scriptproccost
  29400.                 insert #workload_breakdown values (@name, @artid, 9, @taskload)
  29401.                 -- Cost of adding command for the script
  29402.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29403.                 -- Increment scripts counter
  29404.                 select @numscripts = @numscripts + 1
  29405.     
  29406.                 -- Trigger script?
  29407.                 if (@schema_option & 0x100) <> 0x0
  29408.                 begin
  29409.                     -- Cost of script generation
  29410.                     select @taskload = @dmoscriptcost + @scriptproccost
  29411.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  29412.                     -- Cost of adding command for the script
  29413.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29414.                     -- Increment scripts counter
  29415.                     select @numscripts = @numscripts + 1
  29416.                 end 
  29417.         
  29418.                 -- XProp script?
  29419.                 if (@schema_option & 0x2000) <> 0x0
  29420.                 begin
  29421.                     -- Cost of script generation 
  29422.                     select @taskload = @dmoscriptcost + @scriptproccost
  29423.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  29424.                     -- Cost of adding command
  29425.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29426.                     -- Increment scripts counter
  29427.                     select @numscripts = @numscripts + 1
  29428.                 end
  29429.             end        
  29430.  
  29431.             -- Conflict script generation and setting
  29432.             -- Cost of script generation and execution 
  29433.             select @taskload = @dmoscriptcost + @scriptexeccost + @scriptproccost
  29434.             insert #workload_breakdown values (@name, @artid, 21, @taskload)
  29435.  
  29436.             -- Get fast row count from sysindexes for bcp op estimation
  29437.             select @rowcount = 
  29438.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  29439.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  29440.                          else isnull(rowcnt,0)
  29441.                     end
  29442.               from sysindexes 
  29443.              where id = @objid and indid in (0,1)
  29444.  
  29445.             -- For unsynced articles, we need to 
  29446.             -- 1) Add rowguid column 
  29447.             -- 2) Set article procs
  29448.             -- 3) Add merge triggers
  29449.             if @status = 1
  29450.             begin
  29451.                 -- Add rowguid column - use article row count to estimate the cost
  29452.                 select @taskload = (@rowcount * @rowguidper100) / 100
  29453.                 insert #workload_breakdown values (@name, @artid, 15, @taskload) 
  29454.       
  29455.                 -- Set article procs
  29456.                 select @taskload = @setartprocs
  29457.                 insert #workload_breakdown values (@name, @artid, 16, @taskload)
  29458.  
  29459.                 -- Add merge triggers    
  29460.                 select @taskload = @addmergetriggers 
  29461.                 insert #workload_breakdown values (@name, @artid, 17, @taskload)
  29462.  
  29463.                 -- Increment the number of unsynced articles
  29464.                 select @numunsyncedarticles = @numunsyncedarticles + 1
  29465.             end
  29466.  
  29467.             -- Increment the total row count
  29468.             select @totalrowcount = @totalrowcount + @rowcount        
  29469.  
  29470.             -- BCP computation            
  29471.             -- Bcp file generation
  29472.             select @taskload = @bcpoverhead + (@rowcount * @totalbcpcostper100) / 100 
  29473.             insert #workload_breakdown values (@name, @artid, 4, @taskload)
  29474.  
  29475.             -- Increment the table articles counter
  29476.             select @numtablearticles = @numtablearticles + 1
  29477.  
  29478.         end    
  29479.  
  29480.         -- System pre-snapshot script required?
  29481.         if @type in (0x40, 0x80)
  29482.         begin
  29483.             select @needsysprescript = 1
  29484.             -- Incrememt the number of pre-script command counter
  29485.             select @numprescriptcommands = @numprescriptcommands + 1
  29486.         end
  29487.  
  29488.         -- Increment the article count
  29489.         select @numarticles = @numarticles + 1
  29490.  
  29491.         fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name,
  29492.             @status
  29493.     end
  29494.         
  29495.     -- The cost of making publication views depends upon the 
  29496.     -- number of unsynced articles
  29497.     if @numunsyncedarticles <> 0
  29498.     begin
  29499.         select @taskload = @numunsyncedarticles * @pubviewperarticle 
  29500.         insert #workload_breakdown values (N'', @zerouuid, 22, @taskload) 
  29501.     end
  29502.  
  29503.     -- Make publication generation - roughly proportional to the number of table
  29504.     -- articles we have
  29505.     select @taskload = @numtablearticles * @genperarticle
  29506.     insert #workload_breakdown values (N'', @zerouuid, 20, @taskload)
  29507.  
  29508.     -- Merge system tables processing 
  29509.     -- Script files
  29510.     select @taskload = 4 * (@dmoscriptcost + @scriptproccost)
  29511.     insert #workload_breakdown values (N'', @zerouuid, 18, @taskload)
  29512.  
  29513.     -- Cost of adding the commands
  29514.     select @addcommandcost = @addcommandcost + 4
  29515.  
  29516.     -- Bcp files - Generated only when the publication is not enabled for
  29517.     -- dynamic filters
  29518.     if @dynamic_filters = 0
  29519.     begin
  29520.         if exists (select * from sysobjects where name = N'MSmerge_contents')
  29521.         begin
  29522.             select @rowcount = 
  29523.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  29524.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  29525.                          else isnull(rowcnt,0)       
  29526.                     end
  29527.               from sysindexes 
  29528.              where id = object_id('dbo.MSmerge_contents') 
  29529.                and indid in (0,1)
  29530.             select @systablesrowcount = @systablesrowcount + @rowcount
  29531.         end
  29532.         if exists (select * from sysobjects where name = N'MSmerge_tombstones')
  29533.         begin
  29534.             select @rowcount = 
  29535.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  29536.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  29537.                          else isnull(rowcnt,0)       
  29538.                     end
  29539.               from sysindexes 
  29540.              where id = object_id('dbo.MSmerge_tombstoness') 
  29541.                and indid in (0,1)
  29542.             select @systablesrowcount = @systablesrowcount + @rowcount
  29543.         end
  29544.         if exists (select * from sysobjects where name = N'MSmerge_genhistory')
  29545.         begin
  29546.             select @rowcount = 
  29547.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  29548.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  29549.                          else isnull(rowcnt,0)       
  29550.                     end
  29551.               from sysindexes 
  29552.              where id = object_id('dbo.MSmerge_genhistory') 
  29553.                and indid in (0,1)
  29554.             select @systablesrowcount = @systablesrowcount + @rowcount
  29555.         end
  29556.     end
  29557.     if exists (select * from sysobjects where name = N'sysmergesubsetfilters')
  29558.     begin
  29559.         select @rowcount = count(*) from sysmergesubsetfilters
  29560.         select @systablesrowcount = @systablesrowcount + @rowcount 
  29561.     end
  29562.  
  29563.     select @taskload = (4 * @bcpoverhead) + (@systablesrowcount * @totalbcpcostper100) / 100 
  29564.     insert #workload_breakdown values (N'', @zerouuid, 19, @taskload)
  29565.     select @totalrowcount = @totalrowcount + @systablesrowcount
  29566.  
  29567.     -- System pre-snapshot script processing cost 
  29568.     if @needsysprescript = 1
  29569.     begin
  29570.         select @taskload = @syspreoverhead + 
  29571.                 (@numprescriptcommands * @syspreper2commands) / 2 +
  29572.                @scriptproccost
  29573.         insert #workload_breakdown values (N'', @zerouuid, 7, @taskload)         
  29574.         select @numscripts = @numscripts + 1
  29575.     end
  29576.  
  29577.     -- Cost of flushing folder for the scripts 
  29578.     if @compress_snapshot = 1
  29579.     begin
  29580.         select @taskload = (@numscripts * @flushper2scripts) / 2
  29581.         insert #workload_breakdown values (N'', @zerouuid, 8, @taskload) 
  29582.     end
  29583.  
  29584.     -- Cost for flushing the cabinet
  29585.     if @compress_snapshot = 1
  29586.     begin
  29587.         select @taskload = (@numscripts * @flushcabper5scripts / 5) +
  29588.                            (@totalrowcount * @flushcabper500bcprows / 500)
  29589.         insert #workload_breakdown values (N'', @zerouuid, 14, @taskload)
  29590.     end
  29591.  
  29592.     -- Add the total add commands cost
  29593.     insert #workload_breakdown values (N'', @zerouuid, 6, @addcommandstotal)
  29594.  
  29595.     -- Compute the total workload and put that in the 
  29596.     -- workload break down
  29597.     select @bigtaskload = sum(convert(bigint,taskload)) from #workload_breakdown
  29598.     select @taskload =
  29599.             case when @bigtaskload > @maxint then @maxint
  29600.             else @bigtaskload
  29601.             end
  29602.     insert #workload_breakdown values (N'', @zerouuid, 0, @taskload) 
  29603.  
  29604.     select name, taskid, taskload from #workload_breakdown order by artid, taskid asc
  29605.     drop table #workload_breakdown
  29606.     return 0
  29607.  
  29608. Failure:
  29609.     if @table_created = 1
  29610.        drop table #workload_breakdown
  29611.     return 1
  29612. end
  29613. go
  29614.  
  29615. exec dbo.sp_MS_marksystemobject sp_MSestimatemergesnapshotworkload
  29616. go            
  29617.  
  29618. grant execute on dbo.sp_MSestimatemergesnapshotworkload to public
  29619. go
  29620.  
  29621. raiserror(15339,-1,-1,'sp_MSestimatesnapshotworkload')
  29622. go
  29623. create proc sp_MSestimatesnapshotworkload (
  29624.     @publication sysname
  29625.     )
  29626. as
  29627. begin
  29628.     set nocount on
  29629.  
  29630.     declare @taskload                       int
  29631.     declare @bigtaskload                    bigint
  29632.     declare @table_created                  bit
  29633.     declare @retcode                        int
  29634.  
  29635.     -- Publication info
  29636.     declare @pubid                          int
  29637.     declare @compress_snapshot              bit
  29638.     declare @snapshot_in_defaultfolder      bit
  29639.     declare @alt_snapshot_folder            nvarchar(255)
  29640.     declare @enabled_for_internet           bit
  29641.     declare @ftp_password                   nvarchar(524) 
  29642.     declare @ftp_subdirectory               nvarchar(255)
  29643.     declare @pre_snapshot_script            nvarchar(255)
  29644.     declare @post_snapshot_script           nvarchar(255)    
  29645.  
  29646.     -- Per publication summary stats
  29647.     declare @numarticles                    int
  29648.     declare @totalrowcount                  int   
  29649.     declare @needsysprescript               bit
  29650.     declare @copysnapshot                   bit
  29651.     declare @deletefiles                    bit
  29652.     declare @scriptproccost                 int
  29653.     declare @addcommandstotal               int
  29654.     declare @numscripts                     int
  29655.     declare @totalbcpcostper100             int
  29656.     declare @numprescriptcommands           int 
  29657.  
  29658.     select @numarticles = 0
  29659.     select @totalrowcount = 0
  29660.     select @needsysprescript = 0
  29661.     select @copysnapshot = 0
  29662.     select @deletefiles = 0
  29663.     select @scriptproccost = 0
  29664.     select @deletefiles = 0
  29665.     select @addcommandstotal = 0
  29666.     select @numscripts = 0
  29667.     select @totalbcpcostper100 = 0
  29668.     select @numprescriptcommands = 0
  29669.  
  29670.     -- Per article variables
  29671.     declare @artid                          int
  29672.     declare @schema_option                  int
  29673.     declare @creation_script                nvarchar(255)
  29674.     declare @type                           tinyint
  29675.     declare @objid                          int
  29676.     declare @rowcount                       int
  29677.     declare @name                           sysname
  29678.     declare @pre_creation_command           int
  29679.  
  29680.     select @table_created = 0
  29681.  
  29682.     -- Security check
  29683.     select @retcode = 0
  29684.     EXEC @retcode = dbo.sp_MSreplcheck_publish
  29685.     IF @@ERROR <> 0 or @retcode <> 0
  29686.         return (1)
  29687.  
  29688.     select @pubid = null
  29689.     select @compress_snapshot = 0
  29690.     select @snapshot_in_defaultfolder = 0
  29691.     select @alt_snapshot_folder = null
  29692.     select @enabled_for_internet = 0
  29693.     select @ftp_password = null
  29694.     select @ftp_subdirectory = null
  29695.     select @pre_snapshot_script = null
  29696.     select @post_snapshot_script = null
  29697.     -- Validate publication and retrieve publication information 
  29698.     select @pubid = pubid, 
  29699.            @compress_snapshot = compress_snapshot,
  29700.            @snapshot_in_defaultfolder = snapshot_in_defaultfolder,
  29701.            @alt_snapshot_folder = alt_snapshot_folder,
  29702.            @enabled_for_internet = enabled_for_internet,
  29703.            @ftp_password = ftp_password,
  29704.            @ftp_subdirectory = ftp_subdirectory,
  29705.            @pre_snapshot_script = pre_snapshot_script,
  29706.            @post_snapshot_script = post_snapshot_script
  29707.            from syspublications
  29708.      where name = @publication
  29709.     if @pubid = null
  29710.     begin   
  29711.         raiserror(20026, 11, -1, @publication)
  29712.         return (1)
  29713.     end
  29714.  
  29715.     -- An artid of -1 means the task is a per publication
  29716.     -- task
  29717.  
  29718.     -- Task id mapping - This is the list of task whose completion can be 
  29719.     -- reported by the snapshot agent
  29720.     -- 0 - Total workload (not really a task)
  29721.     -- 1 - Schema script generation
  29722.     -- 2 - Trigger script generation 
  29723.     -- 3 - XProp script generation
  29724.     -- 4 - Bcp file generation
  29725.     -- 5 - Activating subscription (estimate number of subscriptions?)
  29726.     -- 6 - Adding snapshot commands
  29727.     -- 7 - System pre-script generation
  29728.     -- 8 - Flushing folder for scripts
  29729.     -- 9 - Constraint script generation
  29730.     -- 10 - Copying pre-script
  29731.     -- 11 - Copying post-script
  29732.     -- 12 - Copying custom schema creation script
  29733.     -- 13 - Index script generation
  29734.     -- 14 - Flushing the cabinet
  29735.     -- 15 - Adding rowguid column
  29736.     -- 16 - Setting article procs
  29737.     -- 17 - Adding merge triggers
  29738.     -- 18 - Generating system table scripts
  29739.     -- 19 - Generating system table bcp files
  29740.     -- 20 - Making publication generation
  29741.     -- 21 - Generating and setting conflict script
  29742.     -- 22 - Generating publication views
  29743.  
  29744.     -- Weights and overheads
  29745.     -- DMO Script generation - 7/script
  29746.     -- BCP 5 overhead + 5/100 rows
  29747.     -- Flush folder for bcp 2/100 rows
  29748.     -- Delete file 2
  29749.     -- System pre-snapshot script 1 overhead + 0.5/pre-creation command
  29750.     -- Copying user file 2
  29751.     -- Adding file to cabinet 1 for scripts and 1/100 rows in bcp file
  29752.     -- Loading article info 3
  29753.     -- Delete bcp file 2/100rows 
  29754.     -- Copy bcp file  2/100rows  
  29755.     -- Flush scripts folder 1/2 scripts
  29756.     -- Flushing cabinet per 5 scripts 1
  29757.     -- Flushing cabinet per 500 rows 1
  29758.  
  29759.     -- Here is the list of cost factors 
  29760.     declare @addcommandcost     int
  29761.     declare @dmoscriptcost      int
  29762.     declare @bcpoverhead        int
  29763.     declare @bcpcostper100      int
  29764.     declare @flushper100        int
  29765.     declare @flushperscript     int
  29766.     declare @delfilecost        int
  29767.     declare @syspreoverhead     int
  29768.     declare @syspreper2commands int
  29769.     declare @addbcptocabper100  int
  29770.     declare @addscripttocab     int
  29771.     declare @copyfilecost       int
  29772.     declare @loadartinfo        int    
  29773.     declare @deletebcpper100    int
  29774.     declare @copybcpper100      int
  29775.     declare @flushper2scripts   int
  29776.     declare @flushcabper5scripts int
  29777.     declare @flushcabper500bcprows int
  29778.     declare @maxint             int
  29779.  
  29780.     select @addcommandcost = 2
  29781.     select @dmoscriptcost = 7
  29782.     select @bcpcostper100 = 20
  29783.     select @bcpoverhead = 2
  29784.     select @flushper100 = 2
  29785.     select @flushperscript = 3
  29786.     select @delfilecost = 2
  29787.     select @syspreoverhead = 1
  29788.     select @syspreper2commands = 1
  29789.     select @addbcptocabper100 = 1
  29790.     select @addscripttocab = 1
  29791.     select @copyfilecost = 2
  29792.     select @loadartinfo = 3    
  29793.     select @deletebcpper100 = 1
  29794.     select @copybcpper100 = 2
  29795.     select @flushper2scripts = 1
  29796.     select @flushcabper5scripts = 1
  29797.     select @flushcabper500bcprows = 1
  29798.     select @maxint = 2147483647
  29799.  
  29800.     create table #workload_breakdown
  29801.     (
  29802.         name        sysname collate database_default,
  29803.         artid       int,
  29804.         taskid      int,
  29805.         taskload    int
  29806.     )
  29807.     if @@error <> 0
  29808.         goto Failure
  29809.  
  29810.     select @table_created = 1
  29811.  
  29812.     -- Per publication work load estimate that can be done using publication
  29813.     -- properties alone
  29814.     
  29815.     -- Adding snapshot header commands
  29816.     
  29817.     -- Snapshot header begins + Snapshot header ends +
  29818.     -- directory command + Snapshot trailer command = 3 * @addcommandcost
  29819.     select @addcommandstotal = 4
  29820.     
  29821.     -- Alternate snapshot folder = 1 * @addcommandcost
  29822.     if @alt_snapshot_folder is not null and
  29823.        @alt_snapshot_folder <> N'' and
  29824.        @snapshot_in_defaultfolder = 1
  29825.     begin
  29826.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29827.     end
  29828.  
  29829.     -- Ftp commands
  29830.     if @enabled_for_internet = 1
  29831.     begin
  29832.         -- ftp_address and ftp_port must be there +=2 * @addcommandcost
  29833.         select @addcommandstotal = @addcommandstotal + 2 * @addcommandcost
  29834.  
  29835.         -- ftp_password += 1 * @addcommandcost
  29836.         if @ftp_password is not null and
  29837.            @ftp_password <> N''
  29838.         begin
  29839.             select @addcommandstotal = @addcommandstotal + @addcommandcost
  29840.         end
  29841.         
  29842.         -- ftp_subdirectory += 1 * @addcommandcost
  29843.         if @ftp_subdirectory is not null and
  29844.            @ftp_subdirectory <> N''
  29845.         begin
  29846.             select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  29847.         end
  29848.     end
  29849.  
  29850.     -- Compressed archive path
  29851.     if @compress_snapshot = 1
  29852.     begin
  29853.         select @addcommandstotal = @addcommandstotal + 1 * @addcommandcost
  29854.     end    
  29855.  
  29856.     -- Snapshot trailer command
  29857.     select @addcommandstotal = @addcommandstotal +  @addcommandcost
  29858.  
  29859.     -- Need to copy files?
  29860.     if @alt_snapshot_folder is not null and @alt_snapshot_folder <> N''
  29861.        and @snapshot_in_defaultfolder = 1 and @compress_snapshot = 0
  29862.     begin
  29863.         select @copysnapshot = 1
  29864.     end
  29865.  
  29866.     -- Compute per-script file post processing cost and bcp cost per 100 rows
  29867.     -- Need to delete files?
  29868.     if (@alt_snapshot_folder is null or @alt_snapshot_folder <> N''
  29869.        or @snapshot_in_defaultfolder = 0) and @compress_snapshot = 1
  29870.     begin
  29871.         select @deletefiles = 1
  29872.     end
  29873.  
  29874.     select @totalbcpcostper100 = @bcpcostper100
  29875.     -- Copy file?
  29876.     if @copysnapshot = 1
  29877.     begin
  29878.         select @scriptproccost = @scriptproccost + @copyfilecost
  29879.         select @totalbcpcostper100 = @totalbcpcostper100 + @copybcpper100
  29880.     end
  29881.  
  29882.     -- Add file to cabinet?
  29883.     if @compress_snapshot = 1
  29884.     begin
  29885.         select @scriptproccost = @scriptproccost + @addscripttocab 
  29886.         select @totalbcpcostper100 = @totalbcpcostper100 + @addbcptocabper100
  29887.     end
  29888.  
  29889.     -- Delete file?
  29890.     if @deletefiles = 1
  29891.     begin 
  29892.         select @scriptproccost = @scriptproccost + @delfilecost
  29893.         select @totalbcpcostper100 = @totalbcpcostper100 + @deletebcpper100
  29894.     end
  29895.  
  29896.     -- Pre/Post-snapshot scripts, has to be computed after the 
  29897.     -- the per-script post-processing cost is calculated 
  29898.     if @pre_snapshot_script is not null and
  29899.        @pre_snapshot_script <> N''
  29900.     begin
  29901.         -- Cost of copying the script file
  29902.         select @taskload = @copyfilecost + @scriptproccost
  29903.         insert #workload_breakdown values (N'', -1, 10, @taskload)        
  29904.         -- Cost of adding the pre-snapshot command
  29905.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29906.         -- Increment scripts counter
  29907.         select @numscripts = @numscripts + 1
  29908.     end
  29909.  
  29910.     if @post_snapshot_script is not null and
  29911.        @post_snapshot_script <> N''
  29912.     begin
  29913.         -- Cost of copying the script file
  29914.         select @taskload = @copyfilecost + @scriptproccost
  29915.         insert #workload_breakdown values (N'', -1, 11, @taskload)
  29916.         -- Cost of adding the post-snapshot command
  29917.         select @addcommandstotal = @addcommandstotal + @addcommandcost
  29918.         -- Increment scripts counter
  29919.         select @numscripts = @numscripts + 1
  29920.     end
  29921.            
  29922.     -- Estimate the break down of per article tasks 
  29923.     declare hCarticles cursor local fast_forward
  29924.     for select artid, creation_script, objid, convert(int, schema_option), type, name, pre_creation_cmd  
  29925.           from sysextendedarticlesview where pubid = @pubid 
  29926.  
  29927.     open hCarticles
  29928.    
  29929.     fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name, @pre_creation_command
  29930.     while (@@fetch_status <> -1)
  29931.     begin
  29932.         if @type = 0x40 -- Schema view articles, may require index scripting
  29933.         begin
  29934.             select @taskload = 0
  29935.             -- See if a custom creation script will be used 
  29936.             if @schema_option = 0 and @creation_script is not null and
  29937.                @creation_script <> N''
  29938.             begin
  29939.                 -- Script generation
  29940.                 select @taskload = @copyfilecost + @scriptproccost
  29941.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  29942.                 -- Cost of adding commands for the custom script
  29943.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29944.                 -- Increment scripts counter
  29945.                 select @numscripts = @numscripts + 1
  29946.                 -- No need to worry about index script
  29947.             end
  29948.             else
  29949.             begin
  29950.                 -- Script generation 
  29951.                 select @taskload = @dmoscriptcost + @scriptproccost
  29952.                 -- Must script out schema script
  29953.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  29954.                 -- Cost of adding the command
  29955.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  29956.                 -- Increment scripts counter
  29957.                 select @numscripts = @numscripts + 1
  29958.  
  29959.                 -- Index script?
  29960.                 if (@schema_option & 0x50) <> 0x0
  29961.                 begin
  29962.                     -- Cost of script generation
  29963.                     select @taskload = @dmoscriptcost + @scriptproccost
  29964.                     insert #workload_breakdown values (@name, @artid, 13, @taskload)
  29965.                     -- Cost of adding command for the script
  29966.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29967.                     -- Increment scripts counter
  29968.                     select @numscripts = @numscripts + 1
  29969.                 end
  29970.  
  29971.                 -- Trigger script?
  29972.                 if (@schema_option & 0x100) <> 0x0
  29973.                 begin
  29974.                     -- Cost of script generation
  29975.                     select @taskload = @dmoscriptcost + @scriptproccost
  29976.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  29977.                     -- Cost of adding command for the script
  29978.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29979.                     -- Increment scripts counter
  29980.                     select @numscripts = @numscripts + 1
  29981.                 end 
  29982.  
  29983.                 -- XProp script?
  29984.                 if (@schema_option & 0x2000) <> 0x0
  29985.                 begin
  29986.                     -- Cost of script generation 
  29987.                     select @taskload = @dmoscriptcost + @scriptproccost
  29988.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  29989.                     -- Cost of adding command
  29990.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  29991.                     -- Increment scripts counter
  29992.                     select @numscripts = @numscripts + 1
  29993.                 end
  29994.             end        
  29995.         end
  29996.         else if @type in (0x08, 0x18, 0x20, 0x80) -- Regular schema or proc exec articles 
  29997.         begin
  29998.             select @taskload = 0
  29999.             -- See if a custom creation script will be used 
  30000.             if @schema_option = 0 and @creation_script is not null and
  30001.                @creation_script <> N''
  30002.             begin
  30003.                 -- Script generation
  30004.                 select @taskload = @copyfilecost + @scriptproccost
  30005.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  30006.                 -- Cost of adding commands for the custom script
  30007.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  30008.                 -- Increment scripts counter
  30009.                 select @numscripts = @numscripts + 1
  30010.             end
  30011.             else 
  30012.             begin
  30013.                 -- Script generation 
  30014.                 select @taskload = @dmoscriptcost + @scriptproccost
  30015.                 -- Must script out schema script
  30016.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  30017.                 -- Cost of adding the command
  30018.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  30019.                 -- Increment scripts counter
  30020.                 select @numscripts = @numscripts + 1
  30021.  
  30022.                 -- XProp script?
  30023.                 if (@schema_option & 0x2000) <> 0x0
  30024.                 begin
  30025.                     -- Cost of script generation 
  30026.                     select @taskload = @dmoscriptcost + @scriptproccost
  30027.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  30028.                     -- Cost of adding command
  30029.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  30030.                 -- Increment scripts counter
  30031.                 select @numscripts = @numscripts + 1
  30032.                 end
  30033.             end
  30034.         end
  30035.         else -- Log based articles, requires bcp
  30036.         begin
  30037.            select @taskload = 0
  30038.            -- See if a custom creation script will be used 
  30039.             if @schema_option = 0 and @creation_script is not null and
  30040.                @creation_script <> N''
  30041.             begin
  30042.                 -- Script generation
  30043.                 select @taskload = @copyfilecost + @scriptproccost
  30044.                 insert #workload_breakdown values (@name, @artid, 12, @taskload)
  30045.                 -- Cost of adding commands for the custom script
  30046.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  30047.                 -- Increment scripts counter
  30048.                 select @numscripts = @numscripts + 1
  30049.                 -- No need to worry about index script
  30050.             end
  30051.             else
  30052.             begin
  30053.                 -- Script generation 
  30054.                 select @taskload = @dmoscriptcost + @scriptproccost
  30055.                 -- Must script out schema script
  30056.                 insert #workload_breakdown values (@name, @artid, 1, @taskload)
  30057.                 -- Cost of adding the command
  30058.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  30059.                 -- Increment scripts counter
  30060.                 select @numscripts = @numscripts + 1
  30061.  
  30062.                 -- Index script is not optional for logbased articles
  30063.                 -- Cost of script generation
  30064.                 select @taskload = @dmoscriptcost + @scriptproccost
  30065.                 insert #workload_breakdown values (@name, @artid, 13, @taskload)
  30066.                 -- Cost of adding command for the script
  30067.                 select @addcommandstotal = @addcommandstotal + @addcommandcost
  30068.                 -- Increment scripts counter
  30069.                 select @numscripts = @numscripts + 1
  30070.  
  30071.                 -- Constraint script?
  30072.                 if (@schema_option & 0xf00) <> 0x0
  30073.                 begin
  30074.                     -- Cost of script generation
  30075.                     select @taskload = @dmoscriptcost + @scriptproccost
  30076.                     insert #workload_breakdown values (@name, @artid, 9, @taskload)
  30077.                     -- Cost of adding command for the script
  30078.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  30079.                     -- Increment scripts counter
  30080.                     select @numscripts = @numscripts + 1
  30081.                 end
  30082.     
  30083.                 -- Trigger script?
  30084.                 if (@schema_option & 0x100) <> 0x0
  30085.                 begin
  30086.                     -- Cost of script generation
  30087.                     select @taskload = @dmoscriptcost + @scriptproccost
  30088.                     insert #workload_breakdown values (@name, @artid, 2, @taskload)
  30089.                     -- Cost of adding command for the script
  30090.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  30091.                     -- Increment scripts counter
  30092.                     select @numscripts = @numscripts + 1
  30093.                 end 
  30094.         
  30095.                 -- XProp script?
  30096.                 if (@schema_option & 0x2000) <> 0x0
  30097.                 begin
  30098.                     -- Cost of script generation 
  30099.                     select @taskload = @dmoscriptcost + @scriptproccost
  30100.                     insert #workload_breakdown values (@name, @artid, 3, @taskload)
  30101.                     -- Cost of adding command
  30102.                     select @addcommandstotal = @addcommandstotal + @addcommandcost
  30103.                     -- Increment scripts counter
  30104.                     select @numscripts = @numscripts + 1
  30105.                 end
  30106.             end        
  30107.         
  30108.             -- Get fast row count from sysindexes for bcp op estimation
  30109.             select @rowcount = 
  30110.                     case when isnull(rowcnt,0) > @maxint then @maxint / 10000
  30111.                          when isnull(rowcnt,0) > @maxint / 10000 then rowcnt / 10000
  30112.                          else isnull(rowcnt,0)
  30113.                     end
  30114.                from sysindexes 
  30115.              where id = @objid 
  30116.                and indid in (0,1)
  30117.  
  30118.             -- Increment the total row count
  30119.             select @totalrowcount = @totalrowcount + @rowcount        
  30120.  
  30121.             -- BCP computation            
  30122.             -- Bcp file generation
  30123.             select @taskload = @bcpoverhead + (@rowcount * @totalbcpcostper100) / 100 
  30124.             insert #workload_breakdown values (@name, @artid, 4, @taskload)
  30125.         end    
  30126.  
  30127.         -- System pre-snapshot script required?
  30128.         if @type in (0x40, 0x80) or ((@type & 0x1)<>0 and @pre_creation_command =  3)
  30129.         begin
  30130.             select @needsysprescript = 1
  30131.             -- Incrememt the number of pre-script command counter
  30132.             select @numprescriptcommands = @numprescriptcommands + 1
  30133.         end
  30134.  
  30135.         -- Increment the article count
  30136.         select @numarticles = @numarticles + 1
  30137.  
  30138.         fetch hCarticles into @artid, @creation_script, @objid, @schema_option, @type, @name, @pre_creation_command
  30139.     end
  30140.     
  30141.     -- System pre-snapshot script processing cost 
  30142.     if @needsysprescript = 1
  30143.     begin
  30144.         select @taskload = @syspreoverhead + 
  30145.                 (@numprescriptcommands * @syspreper2commands) / 2 +
  30146.                @scriptproccost
  30147.         insert #workload_breakdown values (N'', -1, 7, @taskload)         
  30148.         select @numscripts = @numscripts + 1
  30149.     end
  30150.  
  30151.     -- Cost of flushing folder for the scripts 
  30152.     if @compress_snapshot = 1
  30153.     begin
  30154.         select @taskload = (@numscripts * @flushper2scripts) / 2
  30155.         insert #workload_breakdown values (N'', -1, 8, @taskload) 
  30156.     end
  30157.  
  30158.     -- Synctran commands cost?
  30159.         
  30160.  
  30161.     -- Subscription activation cost?
  30162.  
  30163.  
  30164.     -- Cost for flushing the cabinet
  30165.     if @compress_snapshot = 1
  30166.     begin
  30167.         select @taskload = (@numscripts * @flushcabper5scripts / 5) +
  30168.                            (@totalrowcount * @flushcabper500bcprows / 500)
  30169.         insert #workload_breakdown values (N'', -1, 14, @taskload)
  30170.     end
  30171.  
  30172.     -- Add the total add commands cost
  30173.     insert #workload_breakdown values (N'', -1, 6, @addcommandstotal)
  30174.  
  30175.     -- Compute the total workload and put that in the 
  30176.     -- workload break down
  30177.     select @bigtaskload = sum(convert(bigint,taskload)) from #workload_breakdown
  30178.     select @taskload =
  30179.             case when @bigtaskload > @maxint then @maxint
  30180.                  else @bigtaskload
  30181.             end
  30182.     insert #workload_breakdown values (N'', -1, 0, @taskload) 
  30183.  
  30184.     select name, taskid, taskload from #workload_breakdown order by artid, taskid asc
  30185.     drop table #workload_breakdown
  30186.     return 0
  30187.  
  30188. Failure:
  30189.     if @table_created = 1
  30190.        drop table #workload_breakdown
  30191.     return 1
  30192.  
  30193. end
  30194. go
  30195.  
  30196. CREATE FUNCTION system_function_schema.fn_serverid(@servername sysname)
  30197.     RETURNS int
  30198. AS
  30199. BEGIN
  30200.     declare @srvid int
  30201.     select @srvid = srvid from master..sysservers where UPPER(srvname) = UPPER(@servername) collate database_default
  30202.     RETURN (@srvid)
  30203. END    
  30204. go
  30205.  
  30206.  
  30207.  
  30208. GRANT EXECUTE ON system_function_schema.fn_serverid TO PUBLIC
  30209. go
  30210.  
  30211. exec dbo.sp_MS_marksystemobject sp_MSestimatesnapshotworkload
  30212. go            
  30213.  
  30214. --
  30215. -- Name: sp_MSdropfkreferencingarticle
  30216. --
  30217. -- Description: This procedure is used by the distribution agent to drop 
  30218. --              all the foreign key constraints at the subscriber referencing
  30219. --              a replicated table before re-applying snapshot. 
  30220. --
  30221. -- Parameters: @destination_object_name sysname (mandatory) 
  30222. --             @destination_owner_name sysname (optional, default = NULL)
  30223. --
  30224. -- Security: Only members of dbo and sysadmin can execute this procedure
  30225. --
  30226. print 'Creating procedure sp_MSdropfkreferencingarticle'
  30227. print ''
  30228. go
  30229. create procedure sp_MSdropfkreferencingarticle (
  30230.     @destination_object_name sysname,
  30231.     @destination_owner_name sysname = null
  30232.     )
  30233. as
  30234. begin
  30235.     set nocount on 
  30236.     declare @fk_name sysname,
  30237.             @drop_command nvarchar(4000),
  30238.             @fkeyid int,
  30239.             @retcode int,
  30240.             @robject_name sysname,
  30241.             @robject_owner sysname
  30242.     select @retcode = 0    
  30243.  
  30244.     -- Security check
  30245.     exec @retcode = dbo.sp_MSreplcheck_subscribe
  30246.     if @@error <> 0 or @retcode <> 0
  30247.         return 1    
  30248.  
  30249.     select @destination_owner_name = rtrim(ltrim(@destination_owner_name))
  30250.     
  30251.     declare hForeignKeys cursor local fast_forward
  30252.     for 
  30253.         select object_name(sr.constid), sr.fkeyid 
  30254.           from dbo.sysreferences sr
  30255.     inner join dbo.sysconstraints sc
  30256.         on sr.constid = sc.constid
  30257.     inner join dbo.sysobjects so
  30258.         on so.id = sr.rkeyid
  30259.          where so.name = @destination_object_name
  30260.            and (@destination_owner_name is null or
  30261.             @destination_owner_name = N'' or
  30262.             so.uid = user_id(@destination_owner_name))        
  30263.     open hForeignKeys
  30264.     
  30265.     fetch hForeignKeys into @fk_name, @fkeyid
  30266.     
  30267.     while (@@fetch_status <> -1)
  30268.     begin
  30269.         select @robject_name = name, @robject_owner = user_name(uid)
  30270.           from dbo.sysobjects 
  30271.          where id = @fkeyid
  30272.  
  30273.         select @drop_command = N'alter table ' +
  30274.                quotename(@robject_owner) + N'.' +
  30275.                quotename(@robject_name) + 
  30276.                N' drop constraint ' + quotename(@fk_name)
  30277.         exec(@drop_command)
  30278.         if @@error <> 0
  30279.         begin
  30280.             select @retcode = 1
  30281.             goto Failure
  30282.         end    
  30283.         fetch hForeignKeys into @fk_name, @fkeyid 
  30284.     end
  30285.  
  30286. Failure:
  30287.     close hForeignKeys
  30288.     deallocate hForeignKeys
  30289.     return @retcode
  30290. end
  30291. go
  30292. exec sp_MS_marksystemobject sp_MSdropfkreferencingarticle
  30293. go
  30294. --
  30295. -- sp_addscriptexec 
  30296. --
  30297. -- Description: this stored procedure can be used to post a SQL script to all 
  30298. --         subscribers of specified publication.
  30299. --
  30300. -- Parameters:    @publication    sysname        name of a single publication 
  30301. --        @scriptfile    nvarchar(4000)    full path to the SQL script file 
  30302. --        @skiperror    bit        stop or continue upon error
  30303. --
  30304. -- Returns:
  30305. --         0 if success
  30306. --        1 if failure
  30307. --
  30308. create proc sp_addscriptexec (
  30309.     @publication sysname
  30310.     ,@scriptfile nvarchar (4000) 
  30311.     ,@skiperror bit = 0
  30312. )
  30313. as
  30314. declare @directory nvarchar(4000)
  30315. declare @cmd nvarchar(4000)
  30316. declare @filename nvarchar(1024)
  30317. declare @subdirectory nvarchar(1024)
  30318. declare @artid int
  30319. declare @pubid int
  30320. declare @repl_freq int
  30321. declare @retcode int
  30322. declare @category int
  30323. declare @merge_pubid uniqueidentifier
  30324. declare @schemaversion int
  30325. declare @schemaguid uniqueidentifier
  30326.  
  30327. set nocount on
  30328.  
  30329. exec @retcode = dbo.sp_MSreplcheck_publish
  30330. if @@ERROR <> 0 or @retcode <> 0
  30331.     return(1)
  30332.  
  30333. -- Check to see if the database has been activated for publication.
  30334. SELECT @category = category FROM master..sysdatabases WHERE name = DB_NAME() collate database_default
  30335. IF (@category & 1) = 0 and (@category & 4) = 0
  30336. BEGIN
  30337.     RAISERROR (14013, 16, -1)
  30338.     RETURN (1)
  30339. END
  30340.  
  30341. IF @publication IS NULL
  30342. BEGIN
  30343.     RAISERROR (14043, 16, -1, '@publication')
  30344.     RETURN (1)
  30345. END
  30346. ELSE
  30347. BEGIN
  30348.     EXECUTE @retcode = dbo.sp_validname @publication
  30349.         IF @retcode <> 0
  30350.             RETURN (1)
  30351. END
  30352.  
  30353. -- Make sure the publication is available before any cmdshell work.
  30354. if exists (select * from sysobjects where name='syspublications')
  30355. begin
  30356.     select @pubid = pubid, @repl_freq = repl_freq  from syspublications where name = @publication
  30357.     if @pubid is not null
  30358.     begin 
  30359.         -- Doesn't make sense to post for every article in the publication, 
  30360.         -- but artid is required for sp_replpostcmd to work, so just pick one.
  30361.         select top 1 @artid = artid from sysarticles where pubid = @pubid
  30362.         if(@artid is null)
  30363.         begin 
  30364.             RAISERROR (21332, 16, -1, @publication)
  30365.             return (1)
  30366.         end
  30367.         if(@repl_freq = 1) -- don't try to post to snapshot publication, it won't work.
  30368.         begin 
  30369.             RAISERROR (21340, 16, -1, @publication)
  30370.             return (1)
  30371.         end
  30372.     end
  30373. end
  30374. if exists (select * from sysobjects where name='sysmergepublications')
  30375. begin 
  30376.     select @merge_pubid = pubid  from sysmergepublications where name = @publication
  30377.     if @merge_pubid is not null
  30378.     begin 
  30379.         select @schemaversion = 1 + max(schemaversion) from sysmergeschemachange
  30380.         if @schemaversion is null
  30381.             select @schemaversion = 1
  30382.  
  30383.         select @schemaguid = newid()
  30384.     end
  30385. end
  30386.  
  30387. if(@pubid is null and @merge_pubid is null)
  30388. begin 
  30389.     RAISERROR (21332, 16, -1, @publication)
  30390.     return (1)
  30391. end
  30392.  
  30393. exec @retcode = sp_MScopyscriptfile @scriptfile, @cmd=@cmd output
  30394. if @retcode <>0 or @@ERROR<>0
  30395.     return (1)
  30396.  
  30397. select @cmd = convert(nchar(1), @skiperror) + @cmd
  30398. if @pubid is not null
  30399.     exec @retcode = sp_replpostcmd 0, @pubid, @artid, 46, @cmd
  30400. if @merge_pubid is not null
  30401.     exec @retcode = sp_MSinsertschemachange @merge_pubid, NULL, @schemaversion, @schemaguid, 46, @cmd 
  30402. if @retcode <>0 or @@ERROR<>0
  30403.     return (1)
  30404. return (0)
  30405. go
  30406. EXEC dbo.sp_MS_marksystemobject 'sp_addscriptexec'
  30407. go
  30408.  
  30409. -- 
  30410. -- Name: sp_MSmergeupdatelastsyncinfo
  30411. -- 
  30412. -- Description: This procedure sets the last_sync_status, last_sync_summary and 
  30413. -- last updated time for a given merge subscription.
  30414. --
  30415. -- Parameters: @subid                 uniqueidentifier (mandatory)
  30416. --             @last_sync_status     int (mandatory)
  30417. --             @last_sync_summary     sysname (mandatory)
  30418. --
  30419. -- Returns: 0 - succeeded
  30420. --          1 - failed
  30421. --
  30422. -- Security: Sysadmin access only
  30423. --
  30424. print 'Creating procedure sp_MSmergeupdatelastsyncinfo'
  30425. print ''
  30426. go
  30427. create procedure sp_MSmergeupdatelastsyncinfo (
  30428.     @subid                uniqueidentifier,
  30429.     @last_sync_status     int,
  30430.     @last_sync_summary     sysname
  30431. )
  30432. as
  30433.     set nocount on
  30434.     declare @retcode int
  30435.     select @retcode = 0
  30436.  
  30437.     -- Security check
  30438.     exec @retcode = sp_MSreplcheck_subscribe    
  30439.     if @retcode<>0 or @@error<>0
  30440.         return 1
  30441.  
  30442.     if object_id('sysmergesubscriptions') is null 
  30443.         begin
  30444.             raiserror(14055, 16, -1)        
  30445.             return 1
  30446.         end
  30447.         
  30448.     update sysmergesubscriptions 
  30449.         set last_sync_status = @last_sync_status, 
  30450.             last_sync_summary = @last_sync_summary, 
  30451.             last_sync_date = getdate() 
  30452.         where subid = @subid
  30453.     if @@rowcount <> 1 or @@ERROR<>0
  30454.         begin
  30455.             return (1)
  30456.         end            
  30457.     return (0)
  30458. go
  30459.  
  30460. EXEC dbo.sp_MS_marksystemobject 'sp_MSmergeupdatelastsyncinfo'
  30461. go
  30462. grant execute on dbo.sp_MSmergeupdatelastsyncinfo to public
  30463. go
  30464.  
  30465. create procedure sp_MSsetcontext_replagent @agent_type tinyint
  30466. as
  30467. begin
  30468.     declare @cur_context varbinary(128)
  30469.     declare @cur_context_first_byte binary(1)
  30470.     declare @bitmask tinyint
  30471.     
  30472.     -- agent type: snapshot=1, logreader=2, distrib=3, merge=4
  30473.     -- bit to set: snapshot=1, logreader=2, distrib=4, merge=8
  30474.     select @bitmask =    case     
  30475.                             when @agent_type = 1 then 1 
  30476.                             when @agent_type = 2 then 2
  30477.                             when @agent_type = 3 then 4
  30478.                             when @agent_type = 4 then 8
  30479.                         end
  30480.  
  30481.     -- get the current context_info from sysprocesses. remember we only want to modify a bit without changing the rest of the info
  30482.     select @cur_context = context_info from master.dbo.sysprocesses where spid = @@spid
  30483.     -- get the first byte out. the replication agent flags are set in the first byte.
  30484.     select @cur_context_first_byte = substring(@cur_context, 1, 1)
  30485.     -- set the appropriate bit in this one byte (leaving other bits unchanged).
  30486.     select @cur_context_first_byte = (convert(tinyint,@cur_context_first_byte) | @bitmask)
  30487.     -- replace the first byte of the 128 byte binary variable, so that now it has the appropriate bit set.
  30488.     select @cur_context = convert(varbinary(128),stuff (@cur_context, 1, 1, @cur_context_first_byte))
  30489.     -- set the context_info again with the new binary(128) value.
  30490.     set context_info @cur_context
  30491. end
  30492. go
  30493. EXEC dbo.sp_MS_marksystemobject 'sp_MSsetcontext_replagent'
  30494. go
  30495. grant execute on dbo.sp_MSsetcontext_replagent to public
  30496. go
  30497. create function dbo.fn_isreplmergeagent() returns bit
  30498. as
  30499. begin
  30500.     declare @cur_context varbinary(128)
  30501.     declare @cur_context_first_byte binary(1)
  30502.     declare @bitmask tinyint
  30503.     declare @ismergeagent bit
  30504.     
  30505.     select @bitmask = 8        --     snapshot=1, logreader=2, distrib=4, merge=8
  30506.     
  30507.     -- get the current context_info from sysprocesses. 
  30508.     select @cur_context = context_info from master.dbo.sysprocesses where spid = @@spid
  30509.     -- get the first byte out of the 128 byte array.
  30510.     select @cur_context_first_byte = substring(@cur_context, 1, 1)
  30511.     -- check whether it has the merge agent bit set.
  30512.     select @bitmask = (convert(tinyint,@cur_context_first_byte) & @bitmask)
  30513.     -- set the return value appropriately.
  30514.     select @ismergeagent = case when @bitmask = 0 then 0 else 1 end
  30515.  
  30516.     return @ismergeagent
  30517. end
  30518. go
  30519. grant execute on dbo.fn_isreplmergeagent to public
  30520. go
  30521. grant execute on dbo.sp_MSestimatesnapshotworkload to public
  30522. go
  30523.  
  30524. grant execute on dbo.sp_helpreplicationoption to public
  30525. go
  30526.  
  30527. grant execute on dbo.sp_addpullsubscription to public
  30528. go
  30529.  
  30530. grant execute on dbo.sp_addpullsubscription_agent to public
  30531. go
  30532.  
  30533. grant execute on dbo.sp_droppullsubscription to public
  30534. go
  30535.  
  30536. grant execute on dbo.sp_helppullsubscription to public
  30537. go
  30538.  
  30539. grant execute on dbo.sp_helpreplicationdboption to public
  30540. go
  30541.  
  30542. grant exec on dbo.sp_addqueued_artinfo to public
  30543. grant exec on dbo.sp_addsynctriggers to public
  30544. grant exec on dbo.sp_setreplfailovermode to public
  30545. grant exec on dbo.sp_helpreplfailovermode to public
  30546. go
  30547.  
  30548. grant exec on dbo.sp_MScheck_agent_instance to public
  30549. go
  30550.  
  30551. grant exec on dbo.sp_get_distributor to public
  30552. go
  30553.  
  30554. grant exec on dbo.sp_table_validation to public
  30555.  
  30556. grant exec on dbo.sp_addmergepullsubscription to public
  30557.  
  30558. grant exec on dbo.sp_dropmergepullsubscription to public
  30559.  
  30560. grant exec on dbo.sp_changemergepullsubscription to public
  30561.  
  30562. grant exec on dbo.sp_helpmergepullsubscription to public
  30563.  
  30564. grant exec on dbo.sp_addmergepullsubscription_agent to public
  30565. go
  30566.  
  30567. grant exec on dbo.sp_helpsubscription_properties to public
  30568.  
  30569. grant exec on dbo.sp_change_subscription_properties to public
  30570.  
  30571. grant exec on dbo.sp_MSget_publisher_rpc to public
  30572.  
  30573. grant exec on dbo.sp_MSreplcheck_subscribe to public
  30574.  
  30575. grant exec on dbo.sp_link_publication to public
  30576.  
  30577. grant exec on dbo.sp_MS_replication_installed to public
  30578.  
  30579. grant exec on dbo.sp_MSrepl_linkedservers_rowset to public
  30580.  
  30581. grant exec on dbo.sp_MScreate_sub_tables to public
  30582. grant exec on dbo.sp_MSupdate_mqserver_subdb to public
  30583.  
  30584. grant exec on dbo.sp_MSget_jobstate to public
  30585. go
  30586. grant exec on dbo.sp_MSrepl_isdbowner to public
  30587. grant exec on dbo.sp_MSscript_pkvar_assignment to public
  30588. go
  30589. grant exec on dbo.sp_MSreplraiserror to public
  30590. grant exec on dbo.sp_check_sync_trigger to public
  30591. grant exec on dbo.sp_check_for_sync_trigger to public
  30592. go
  30593. grant execute on dbo.sp_MSscript_where_clause to public
  30594. grant execute on dbo.sp_MSscript_params to public
  30595. grant execute on dbo.sp_MSscript_procbodystart to public
  30596. grant execute on dbo.sp_MSscript_begintrig1 to public
  30597. grant execute on dbo.sp_MSscript_begintrig2 to public
  30598. grant execute on dbo.sp_MSscript_endtrig to public
  30599. grant execute on dbo.sp_MSscript_trigger_variables to public
  30600. grant execute on dbo.sp_MSscript_trigger_assignment to public
  30601. grant execute on dbo.sp_MSscript_trigger_fetch_statement to public
  30602. grant execute on dbo.sp_MSscript_trigger_exec_rpc  to public
  30603. grant execute on dbo.sp_MSscript_trigger_update_checks to public
  30604. grant execute on dbo.sp_MSscript_trigger_updates to public
  30605. grant execute on dbo.sp_MSscript_singlerow_trigger to public 
  30606. grant execute on dbo.sp_MSscript_multirow_trigger to public
  30607. grant execute on dbo.sp_MSscript_sync_ins_trig to public
  30608. grant execute on dbo.sp_MSscript_sync_upd_trig to public
  30609. grant execute on dbo.sp_MSscript_sync_del_trig to public
  30610. grant execute on dbo.sp_MSscript_pkvar_assignment to public
  30611. grant execute on dbo.sp_MSreplcheck_pull to public
  30612. grant execute on dbo.sp_MSdropfkreferencingarticle to public
  30613. go
  30614. grant execute on dbo.sp_enableagentoffload to public
  30615. grant execute on dbo.sp_disableagentoffload to public
  30616. grant execute on dbo.sp_getagentoffloadinfo to public
  30617. grant execute on dbo.sp_MSsub_check_identity to public
  30618. grant execute on dbo.sp_MSsub_set_identity to public
  30619. grant execute on dbo.sp_copysubscription to public
  30620. grant execute on dbo.sp_attachsubscription to public
  30621. grant execute on dbo.sp_MSadd_compensating_cmd to public
  30622. grant execute on dbo.sp_MSsendtosqlqueue to public
  30623. grant execute on dbo.sp_MSretrieve_publication_attributes to public
  30624. grant execute on dbo.sp_MScleanup_publication_ADinfo to public
  30625. go
  30626.  
  30627. grant execute on dbo.fn_varbintohexstr to public
  30628. grant execute on dbo.fn_varbintohexsubstring to public
  30629. grant execute on dbo.fn_MSgensqescstr to public
  30630. go
  30631.  
  30632. grant execute on dbo.fn_MSsharedversion to public
  30633. grant execute on dbo.sp_MSgettools_path to public
  30634. grant execute on dbo.sp_MSget_shared_agent to public
  30635. grant execute on dbo.sp_addscriptexec to public
  30636. grant execute on dbo.sp_MSgetlastupdatedtime to public
  30637. go
  30638.  
  30639. grant execute on system_function_schema.fn_replquotename to public
  30640. grant execute on system_function_schema.fn_chariswhitespace to public
  30641. grant execute on system_function_schema.fn_generateparameterpattern to public
  30642. grant execute on system_function_schema.fn_skipparameterargument to public
  30643. grant execute on system_function_schema.fn_removeparameterwithargument to public
  30644. grant execute on system_function_schema.fn_updateparameterwithargument to public
  30645. grant execute on system_function_schema.fn_repluniquename to public
  30646. go
  30647.  
  30648.  
  30649. dump tran master with no_log
  30650. go
  30651. sp_configure 'allow updates',0
  30652. go
  30653. reconfigure with override
  30654. go
  30655.  
  30656. print ''
  30657. print 'Checking objects created by replsys.sql.'
  30658. go
  30659.  
  30660. --obsolete   exec dbo.sp_check_objects 'repl'
  30661. exec dbo.sp_MS_upd_sysobj_category 2  --set sysobjects.category | 2 based on crdate.
  30662. go
  30663.  
  30664. print ''
  30665. print 'replsys.sql completed successfully.'
  30666. go
  30667.  
  30668. dump tran master with no_log
  30669. go
  30670. checkpoint
  30671. go
  30672.  
  30673.